faster DefineBitsLosslessX reading

This commit is contained in:
honfika@gmail.com
2015-05-08 20:54:48 +02:00
parent 8a784d2d0b
commit 6d49dc584d
13 changed files with 7173 additions and 7030 deletions

View File

@@ -1,285 +1,282 @@
/*
* Copyright (C) 2010-2015 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;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
import com.jpexs.decompiler.flash.types.ARGB;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.SerializableImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.InflaterInputStream;
public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
@SWFType(BasicType.UI16)
public int characterID;
@SWFType(BasicType.UI8)
public int bitmapFormat;
@SWFType(BasicType.UI16)
public int bitmapWidth;
@SWFType(BasicType.UI16)
public int bitmapHeight;
@SWFType(BasicType.UI8)
@Conditional(value = "bitmapFormat", options = {FORMAT_8BIT_COLORMAPPED})
public int bitmapColorTableSize;
public ByteArrayRange zlibBitmapData; //TODO: Parse ALPHACOLORMAPDATA,ALPHABITMAPDATA
public static final int FORMAT_8BIT_COLORMAPPED = 3;
public static final int FORMAT_32BIT_ARGB = 5;
@HideInRawEdit
private ALPHACOLORMAPDATA colorMapData;
@HideInRawEdit
private ALPHABITMAPDATA bitmapData;
@Internal
private boolean decompressed = false;
public static final int ID = 36;
@Override
public int getCharacterId() {
return characterID;
}
private byte[] createEmptyImage() {
try {
ALPHABITMAPDATA bitmapData = new ALPHABITMAPDATA();
bitmapData.bitmapPixelData = new ARGB[1];
bitmapData.bitmapPixelData[0] = new ARGB();
bitmapData.bitmapPixelData[0].alpha = 0xff;
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeALPHABITMAPDATA(bitmapData, FORMAT_32BIT_ARGB, 1, 1);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
return zlibOS.toByteArray();
} catch (IOException ex) {
Logger.getLogger(DefineBitsLossless2Tag.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
@Override
public void setImage(byte[] data) throws IOException {
SerializableImage image = new SerializableImage(ImageHelper.read(new ByteArrayInputStream(data)));
ALPHABITMAPDATA bitmapData = new ALPHABITMAPDATA();
int width = image.getWidth();
int height = image.getHeight();
bitmapData.bitmapPixelData = new ARGB[width * height];
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
for (int pos = 0; pos < pixels.length; pos++) {
int argb = pixels[pos];
int a = (argb >> 24) & 0xff;
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb) & 0xff;
r = r * a / 255;
g = g * a / 255;
b = b * a / 255;
bitmapData.bitmapPixelData[pos] = new ARGB();
bitmapData.bitmapPixelData[pos].alpha = a;
bitmapData.bitmapPixelData[pos].red = r;
bitmapData.bitmapPixelData[pos].green = g;
bitmapData.bitmapPixelData[pos].blue = b;
}
int format = FORMAT_32BIT_ARGB;
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeALPHABITMAPDATA(bitmapData, format, width, height);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray());
bitmapFormat = format;
bitmapWidth = width;
bitmapHeight = height;
decompressed = false;
clearCache();
setModified(true);
}
/**
* Constructor
*
* @param swf
*/
public DefineBitsLossless2Tag(SWF swf) {
super(swf, ID, "DefineBitsLossless2", null);
characterID = swf.getNextCharacterId();
bitmapFormat = DefineBitsLossless2Tag.FORMAT_32BIT_ARGB;
bitmapWidth = 1;
bitmapHeight = 1;
zlibBitmapData = new ByteArrayRange(createEmptyImage());
}
public DefineBitsLossless2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, "DefineBitsLossless2", data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterID = sis.readUI16("characterID");
bitmapFormat = sis.readUI8("bitmapFormat");
bitmapWidth = sis.readUI16("bitmapWidth");
bitmapHeight = sis.readUI16("bitmapHeight");
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
bitmapColorTableSize = sis.readUI8("bitmapColorTableSize");
}
zlibBitmapData = sis.readByteRangeEx(sis.available(), "zlibBitmapData");
}
public ALPHACOLORMAPDATA getColorMapData() {
if (!decompressed) {
uncompressData();
}
return colorMapData;
}
public ALPHABITMAPDATA getBitmapData() {
if (!decompressed) {
uncompressData();
}
return bitmapData;
}
private void uncompressData() {
try {
SWFInputStream sis = new SWFInputStream(swf, Helper.readStream(new InflaterInputStream(new ByteArrayInputStream(zlibBitmapData.getArray(), zlibBitmapData.getPos(), zlibBitmapData.getLength()))));
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
colorMapData = sis.readALPHACOLORMAPDATA(bitmapColorTableSize, bitmapWidth, bitmapHeight, "colorMapData");
}
if (bitmapFormat == FORMAT_32BIT_ARGB) {
bitmapData = sis.readALPHABITMAPDATA(bitmapFormat, bitmapWidth, bitmapHeight, "bitmapData");
}
} catch (IOException ex) {
}
decompressed = true;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterID);
sos.writeUI8(bitmapFormat);
sos.writeUI16(bitmapWidth);
sos.writeUI16(bitmapHeight);
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
sos.writeUI8(bitmapColorTableSize);
}
sos.write(zlibBitmapData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public String getImageFormat() {
return "png";
}
@Override
public InputStream getImageData() {
return null;
}
@Override
public SerializableImage getImage() {
if (cachedImage != null) {
return cachedImage;
}
SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_ARGB);
ALPHACOLORMAPDATA colorMapData = null;
ALPHABITMAPDATA bitmapData = null;
if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_8BIT_COLORMAPPED) {
colorMapData = getColorMapData();
}
if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_32BIT_ARGB) {
bitmapData = getBitmapData();
}
int pos32aligned = 0;
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
int c = 0;
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_8BIT_COLORMAPPED)) {
int colorTableIndex = colorMapData.colorMapPixelData[pos32aligned] & 0xff;
if (colorTableIndex < colorMapData.colorTableRGB.length) {
c = multiplyAlpha(colorMapData.colorTableRGB[colorTableIndex].toInt());
}
}
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_32BIT_ARGB)) {
c = multiplyAlpha(bitmapData.bitmapPixelData[pos].toInt());
}
bi.setRGB(x, y, c);
pos32aligned++;
pos++;
}
while ((pos32aligned % 4 != 0)) {
pos32aligned++;
}
}
cachedImage = bi;
return bi;
}
@Override
public void setCharacterId(int characterId) {
this.characterID = characterId;
}
}
/*
* Copyright (C) 2010-2015 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;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.SerializableImage;
import com.jpexs.helpers.Stopwatch;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.InflaterInputStream;
public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
@SWFType(BasicType.UI16)
public int characterID;
@SWFType(BasicType.UI8)
public int bitmapFormat;
@SWFType(BasicType.UI16)
public int bitmapWidth;
@SWFType(BasicType.UI16)
public int bitmapHeight;
@SWFType(BasicType.UI8)
@Conditional(value = "bitmapFormat", options = {FORMAT_8BIT_COLORMAPPED})
public int bitmapColorTableSize;
public ByteArrayRange zlibBitmapData; //TODO: Parse ALPHACOLORMAPDATA,ALPHABITMAPDATA
public static final int FORMAT_8BIT_COLORMAPPED = 3;
public static final int FORMAT_32BIT_ARGB = 5;
@HideInRawEdit
private ALPHACOLORMAPDATA colorMapData;
@HideInRawEdit
private ALPHABITMAPDATA bitmapData;
@Internal
private boolean decompressed = false;
public static final int ID = 36;
@Override
public int getCharacterId() {
return characterID;
}
private byte[] createEmptyImage() {
try {
ALPHABITMAPDATA bitmapData = new ALPHABITMAPDATA();
bitmapData.bitmapPixelData = new int[]{0xff000000};
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeALPHABITMAPDATA(bitmapData, FORMAT_32BIT_ARGB, 1, 1);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
return zlibOS.toByteArray();
} catch (IOException ex) {
Logger.getLogger(DefineBitsLossless2Tag.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
@Override
public void setImage(byte[] data) throws IOException {
SerializableImage image = new SerializableImage(ImageHelper.read(new ByteArrayInputStream(data)));
ALPHABITMAPDATA bitmapData = new ALPHABITMAPDATA();
int width = image.getWidth();
int height = image.getHeight();
bitmapData.bitmapPixelData = new int[width * height];
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
for (int pos = 0; pos < pixels.length; pos++) {
int argb = pixels[pos];
int a = (argb >> 24) & 0xff;
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb) & 0xff;
r = r * a / 255;
g = g * a / 255;
b = b * a / 255;
bitmapData.bitmapPixelData[pos] = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
}
int format = FORMAT_32BIT_ARGB;
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeALPHABITMAPDATA(bitmapData, format, width, height);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray());
bitmapFormat = format;
bitmapWidth = width;
bitmapHeight = height;
decompressed = false;
clearCache();
setModified(true);
}
/**
* Constructor
*
* @param swf
*/
public DefineBitsLossless2Tag(SWF swf) {
super(swf, ID, "DefineBitsLossless2", null);
characterID = swf.getNextCharacterId();
bitmapFormat = DefineBitsLossless2Tag.FORMAT_32BIT_ARGB;
bitmapWidth = 1;
bitmapHeight = 1;
zlibBitmapData = new ByteArrayRange(createEmptyImage());
}
public DefineBitsLossless2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, "DefineBitsLossless2", data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterID = sis.readUI16("characterID");
bitmapFormat = sis.readUI8("bitmapFormat");
bitmapWidth = sis.readUI16("bitmapWidth");
bitmapHeight = sis.readUI16("bitmapHeight");
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
bitmapColorTableSize = sis.readUI8("bitmapColorTableSize");
}
zlibBitmapData = sis.readByteRangeEx(sis.available(), "zlibBitmapData");
}
public ALPHACOLORMAPDATA getColorMapData() {
if (!decompressed) {
uncompressData();
}
return colorMapData;
}
public ALPHABITMAPDATA getBitmapData() {
if (!decompressed) {
uncompressData();
}
return bitmapData;
}
private void uncompressData() {
try {
SWFInputStream sis = new SWFInputStream(swf, Helper.readStream(new InflaterInputStream(new ByteArrayInputStream(zlibBitmapData.getArray(), zlibBitmapData.getPos(), zlibBitmapData.getLength()))));
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
colorMapData = sis.readALPHACOLORMAPDATA(bitmapColorTableSize, bitmapWidth, bitmapHeight, "colorMapData");
}
if (bitmapFormat == FORMAT_32BIT_ARGB) {
Stopwatch sw = Stopwatch.startNew();
bitmapData = sis.readALPHABITMAPDATA(bitmapFormat, bitmapWidth, bitmapHeight, "bitmapData");
sw.stop();
System.out.println("uncompress: " + sw.getElapsedMilliseconds());
}
} catch (IOException ex) {
}
decompressed = true;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterID);
sos.writeUI8(bitmapFormat);
sos.writeUI16(bitmapWidth);
sos.writeUI16(bitmapHeight);
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
sos.writeUI8(bitmapColorTableSize);
}
sos.write(zlibBitmapData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public String getImageFormat() {
return "png";
}
@Override
public InputStream getImageData() {
return null;
}
@Override
public SerializableImage getImage() {
if (cachedImage != null) {
return cachedImage;
}
SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_ARGB);
ALPHACOLORMAPDATA colorMapData = null;
ALPHABITMAPDATA bitmapData = null;
if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_8BIT_COLORMAPPED) {
colorMapData = getColorMapData();
}
if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_32BIT_ARGB) {
bitmapData = getBitmapData();
}
int pos32aligned = 0;
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
int c = 0;
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_8BIT_COLORMAPPED)) {
int colorTableIndex = colorMapData.colorMapPixelData[pos32aligned] & 0xff;
if (colorTableIndex < colorMapData.colorTableRGB.length) {
c = multiplyAlpha(colorMapData.colorTableRGB[colorTableIndex]);
}
}
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_32BIT_ARGB)) {
c = multiplyAlpha(bitmapData.bitmapPixelData[pos]);
}
bi.setRGB(x, y, c);
pos32aligned++;
pos++;
}
while ((pos32aligned % 4 != 0)) {
pos32aligned++;
}
}
cachedImage = bi;
return bi;
}
@Override
public void setCharacterId(int characterId) {
this.characterID = characterId;
}
}

View File

@@ -1,287 +1,283 @@
/*
* Copyright (C) 2010-2015 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;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.BITMAPDATA;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.COLORMAPDATA;
import com.jpexs.decompiler.flash.types.PIX24;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.SerializableImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.InflaterInputStream;
public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
@SWFType(BasicType.UI16)
public int characterID;
@SWFType(BasicType.UI8)
public int bitmapFormat;
@SWFType(BasicType.UI16)
public int bitmapWidth;
@SWFType(BasicType.UI16)
public int bitmapHeight;
@SWFType(BasicType.UI8)
@Conditional(value = "bitmapFormat", options = {FORMAT_8BIT_COLORMAPPED})
public int bitmapColorTableSize;
public ByteArrayRange zlibBitmapData; //TODO: Parse COLORMAPDATA,BITMAPDATA
public static final int FORMAT_8BIT_COLORMAPPED = 3;
public static final int FORMAT_15BIT_RGB = 4;
public static final int FORMAT_24BIT_RGB = 5;
@HideInRawEdit
private COLORMAPDATA colorMapData;
@HideInRawEdit
private BITMAPDATA bitmapData;
@Internal
private boolean decompressed = false;
public static final int ID = 20;
private byte[] createEmptyImage() {
try {
BITMAPDATA bitmapData = new BITMAPDATA();
bitmapData.bitmapPixelDataPix24 = new PIX24[1];
bitmapData.bitmapPixelDataPix24[0] = new PIX24();
bitmapData.bitmapPixelDataPix24[0].reserved = 0xff;
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeBITMAPDATA(bitmapData, FORMAT_24BIT_RGB, 1, 1);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
return zlibOS.toByteArray();
} catch (IOException ex) {
Logger.getLogger(DefineBitsLosslessTag.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
@Override
public void setImage(byte[] data) throws IOException {
SerializableImage image = new SerializableImage(ImageHelper.read(new ByteArrayInputStream(data)));
int width = image.getWidth();
int height = image.getHeight();
bitmapData = new BITMAPDATA();
bitmapData.bitmapPixelDataPix24 = new PIX24[width * height];
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
for (int pos = 0; pos < pixels.length; pos++) {
int argb = pixels[pos];
//int a = (argb >> 24) & 0xff;
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb) & 0xff;
bitmapData.bitmapPixelDataPix24[pos] = new PIX24();
bitmapData.bitmapPixelDataPix24[pos].red = r;
bitmapData.bitmapPixelDataPix24[pos].green = g;
bitmapData.bitmapPixelDataPix24[pos].blue = b;
bitmapData.bitmapPixelDataPix24[pos].reserved = 0xff; //documentation says 0, but image is sometimes broken with 0, so there is 0xff, which works (maybe alpha?)
}
int format = FORMAT_24BIT_RGB;
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeBITMAPDATA(bitmapData, format, width, height);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray());
bitmapFormat = format;
bitmapWidth = width;
bitmapHeight = height;
decompressed = false;
clearCache();
setModified(true);
}
@Override
public InputStream getImageData() {
return null;
}
@Override
public SerializableImage getImage() {
if (cachedImage != null) {
return cachedImage;
}
SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_RGB);
COLORMAPDATA colorMapData = null;
BITMAPDATA bitmapData = null;
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_8BIT_COLORMAPPED) {
colorMapData = getColorMapData();
}
if ((bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) || (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB)) {
bitmapData = getBitmapData();
}
int pos32aligned = 0;
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
int c = 0;
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_8BIT_COLORMAPPED) {
int colorTableIndex = colorMapData.colorMapPixelData[pos32aligned] & 0xff;
if (colorTableIndex < colorMapData.colorTableRGB.length) {
RGB color = colorMapData.colorTableRGB[colorTableIndex];
c = color.toInt();
}
}
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) {
c = new RGB(bitmapData.bitmapPixelDataPix15[pos].red * 8, bitmapData.bitmapPixelDataPix15[pos].green * 8, bitmapData.bitmapPixelDataPix15[pos].blue * 8).toInt();
}
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) {
c = new RGB(bitmapData.bitmapPixelDataPix24[pos].red, bitmapData.bitmapPixelDataPix24[pos].green, bitmapData.bitmapPixelDataPix24[pos].blue).toInt();
}
bi.setRGB(x, y, c);
pos32aligned++;
pos++;
}
while ((pos32aligned % 4 != 0)) {
pos32aligned++;
}
}
cachedImage = bi;
return bi;
}
@Override
public int getCharacterId() {
return characterID;
}
public COLORMAPDATA getColorMapData() {
if (!decompressed) {
uncompressData();
}
return colorMapData;
}
public BITMAPDATA getBitmapData() {
if (!decompressed) {
uncompressData();
}
return bitmapData;
}
private void uncompressData() {
try {
SWFInputStream sis = new SWFInputStream(swf, Helper.readStream(new InflaterInputStream(new ByteArrayInputStream(zlibBitmapData.getArray(), zlibBitmapData.getPos(), zlibBitmapData.getLength()))));
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
colorMapData = sis.readCOLORMAPDATA(bitmapColorTableSize, bitmapWidth, bitmapHeight, "colorMapData");
}
if ((bitmapFormat == FORMAT_15BIT_RGB) || (bitmapFormat == FORMAT_24BIT_RGB)) {
bitmapData = sis.readBITMAPDATA(bitmapFormat, bitmapWidth, bitmapHeight, "bitmapData");
}
} catch (IOException ex) {
}
decompressed = true;
}
/**
* Constructor
*
* @param swf
*/
public DefineBitsLosslessTag(SWF swf) {
super(swf, ID, "DefineBitsLossless", null);
characterID = swf.getNextCharacterId();
bitmapFormat = DefineBitsLosslessTag.FORMAT_24BIT_RGB;
bitmapWidth = 1;
bitmapHeight = 1;
zlibBitmapData = new ByteArrayRange(createEmptyImage());
}
public DefineBitsLosslessTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, "DefineBitsLossless", data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterID = sis.readUI16("characterID");
bitmapFormat = sis.readUI8("bitmapFormat");
bitmapWidth = sis.readUI16("bitmapWidth");
bitmapHeight = sis.readUI16("bitmapHeight");
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
bitmapColorTableSize = sis.readUI8("bitmapColorTableSize");
}
zlibBitmapData = sis.readByteRangeEx(sis.available(), "zlibBitmapData");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterID);
sos.writeUI8(bitmapFormat);
sos.writeUI16(bitmapWidth);
sos.writeUI16(bitmapHeight);
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
sos.writeUI8(bitmapColorTableSize);
}
sos.write(zlibBitmapData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public String getImageFormat() {
return "png";
}
@Override
public void setCharacterId(int characterId) {
this.characterID = characterId;
}
}
/*
* Copyright (C) 2010-2015 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;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.BITMAPDATA;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.COLORMAPDATA;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.SerializableImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.InflaterInputStream;
public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
@SWFType(BasicType.UI16)
public int characterID;
@SWFType(BasicType.UI8)
public int bitmapFormat;
@SWFType(BasicType.UI16)
public int bitmapWidth;
@SWFType(BasicType.UI16)
public int bitmapHeight;
@SWFType(BasicType.UI8)
@Conditional(value = "bitmapFormat", options = {FORMAT_8BIT_COLORMAPPED})
public int bitmapColorTableSize;
public ByteArrayRange zlibBitmapData; //TODO: Parse COLORMAPDATA,BITMAPDATA
public static final int FORMAT_8BIT_COLORMAPPED = 3;
public static final int FORMAT_15BIT_RGB = 4;
public static final int FORMAT_24BIT_RGB = 5;
@HideInRawEdit
private COLORMAPDATA colorMapData;
@HideInRawEdit
private BITMAPDATA bitmapData;
@Internal
private boolean decompressed = false;
public static final int ID = 20;
private byte[] createEmptyImage() {
try {
BITMAPDATA bitmapData = new BITMAPDATA();
bitmapData.bitmapPixelDataPix24 = new int[]{0xff000000};
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeBITMAPDATA(bitmapData, FORMAT_24BIT_RGB, 1, 1);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
return zlibOS.toByteArray();
} catch (IOException ex) {
Logger.getLogger(DefineBitsLosslessTag.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
@Override
public void setImage(byte[] data) throws IOException {
SerializableImage image = new SerializableImage(ImageHelper.read(new ByteArrayInputStream(data)));
int width = image.getWidth();
int height = image.getHeight();
bitmapData = new BITMAPDATA();
bitmapData.bitmapPixelDataPix24 = new int[width * height];
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
for (int pos = 0; pos < pixels.length; pos++) {
// set the reserved bits to 0xff, because:
// documentation says 0, but image is sometimes broken with 0, so there is 0xff, which works (maybe alpha?)
int argb = pixels[pos] | 0xff000000;
bitmapData.bitmapPixelDataPix24[pos] = argb;
}
int format = FORMAT_24BIT_RGB;
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, getVersion());
sos.writeBITMAPDATA(bitmapData, format, width, height);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, getVersion());
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray());
bitmapFormat = format;
bitmapWidth = width;
bitmapHeight = height;
decompressed = false;
clearCache();
setModified(true);
}
@Override
public InputStream getImageData() {
return null;
}
@Override
public SerializableImage getImage() {
if (cachedImage != null) {
return cachedImage;
}
int[] pixels = new int[bitmapWidth * bitmapHeight];
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_8BIT_COLORMAPPED) {
COLORMAPDATA colorMapData = getColorMapData();
int pos32aligned = 0;
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
int c = 0;
int colorTableIndex = colorMapData.colorMapPixelData[pos32aligned] & 0xff;
if (colorTableIndex < colorMapData.colorTableRGB.length) {
c = colorMapData.colorTableRGB[colorTableIndex];
}
pixels[pos++] = c;
pos32aligned++;
}
while ((pos32aligned % 4 != 0)) {
pos32aligned++;
}
}
} else if ((bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) || (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB)) {
BITMAPDATA bitmapData = getBitmapData();
int pos = 0;
int[] bitmapPixelData = null;
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) {
bitmapPixelData = bitmapData.bitmapPixelDataPix15;
} else if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) {
bitmapPixelData = bitmapData.bitmapPixelDataPix24;
}
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
int c = bitmapPixelData[pos] | 0xff000000;
pixels[pos++] = c;
}
}
}
SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_RGB, pixels);
cachedImage = bi;
return bi;
}
@Override
public int getCharacterId() {
return characterID;
}
public COLORMAPDATA getColorMapData() {
if (!decompressed) {
uncompressData();
}
return colorMapData;
}
public BITMAPDATA getBitmapData() {
if (!decompressed) {
uncompressData();
}
return bitmapData;
}
private void uncompressData() {
try {
byte[] uncompressedData = Helper.readStream(new InflaterInputStream(new ByteArrayInputStream(zlibBitmapData.getArray(), zlibBitmapData.getPos(), zlibBitmapData.getLength())));
SWFInputStream sis = new SWFInputStream(swf, uncompressedData);
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
colorMapData = sis.readCOLORMAPDATA(bitmapColorTableSize, bitmapWidth, bitmapHeight, "colorMapData");
} else if ((bitmapFormat == FORMAT_15BIT_RGB) || (bitmapFormat == FORMAT_24BIT_RGB)) {
bitmapData = sis.readBITMAPDATA(bitmapFormat, bitmapWidth, bitmapHeight, "bitmapData");
}
} catch (IOException ex) {
}
decompressed = true;
}
/**
* Constructor
*
* @param swf
*/
public DefineBitsLosslessTag(SWF swf) {
super(swf, ID, "DefineBitsLossless", null);
characterID = swf.getNextCharacterId();
bitmapFormat = DefineBitsLosslessTag.FORMAT_24BIT_RGB;
bitmapWidth = 1;
bitmapHeight = 1;
zlibBitmapData = new ByteArrayRange(createEmptyImage());
}
public DefineBitsLosslessTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, "DefineBitsLossless", data);
readData(sis, data, 0, false, false, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterID = sis.readUI16("characterID");
bitmapFormat = sis.readUI8("bitmapFormat");
bitmapWidth = sis.readUI16("bitmapWidth");
bitmapHeight = sis.readUI16("bitmapHeight");
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
bitmapColorTableSize = sis.readUI8("bitmapColorTableSize");
}
zlibBitmapData = sis.readByteRangeEx(sis.available(), "zlibBitmapData");
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(characterID);
sos.writeUI8(bitmapFormat);
sos.writeUI16(bitmapWidth);
sos.writeUI16(bitmapHeight);
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
sos.writeUI8(bitmapColorTableSize);
}
sos.write(zlibBitmapData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public String getImageFormat() {
return "png";
}
@Override
public void setCharacterId(int characterId) {
this.characterID = characterId;
}
}

View File

@@ -1,18 +1,19 @@
/*
* Copyright (C) 2010-2015 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.
* License along with this library.
*/
package com.jpexs.decompiler.flash.types;
import java.io.Serializable;
@@ -24,5 +25,5 @@ import java.io.Serializable;
*/
public class ALPHABITMAPDATA implements Serializable {
public int[] bitmapPixelData = new int[0];
}

View File

@@ -25,7 +25,7 @@ import java.io.Serializable;
*/
public class ALPHACOLORMAPDATA implements Serializable {
public RGBA[] colorTableRGB;
public int[] colorTableRGB;
public byte[] colorMapPixelData;
}

View File

@@ -25,7 +25,7 @@ import java.io.Serializable;
*/
public class BITMAPDATA implements Serializable {
public PIX15[] bitmapPixelDataPix15 = new PIX15[0];
public int[] bitmapPixelDataPix15 = new int[0];
public PIX24[] bitmapPixelDataPix24 = new PIX24[0];
public int[] bitmapPixelDataPix24 = new int[0];
}

View File

@@ -23,7 +23,7 @@ import java.io.Serializable;
*/
public class COLORMAPDATA implements Serializable {
public RGB[] colorTableRGB;
public int[] colorTableRGB;
public byte[] colorMapPixelData;
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import java.io.Serializable;
@@ -26,6 +27,10 @@ import java.io.Serializable;
*/
public class PIX15 implements Serializable {
@SWFType(value = BasicType.UB, count = 1)
@Reserved
public int reserved;
/**
* Red color value
*/

View File

@@ -509,7 +509,7 @@ public class Filtering {
return image.getRGB(0, 0, width, image.getHeight(), null, 0, width);
}
private static void setRGB(BufferedImage image, int width, int height, int[] pixels) {
public static void setRGB(BufferedImage image, int width, int height, int[] pixels) {
int type = image.getType();
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) {
image.getRaster().setDataElements(0, 0, width, height, pixels);

View File

@@ -61,6 +61,15 @@ public class SerializableImage implements Serializable {
image = new BufferedImage(width, height, imageType);
}
public SerializableImage(int width, int height, int imageType, int[] pixels) {
if (imageType != BufferedImage.TYPE_INT_ARGB && imageType != BufferedImage.TYPE_INT_RGB) {
throw new Error("Unsuppported image type: " + imageType);
}
image = new BufferedImage(width, height, imageType);
image.getRaster().setDataElements(0, 0, width, height, pixels);
}
public SerializableImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable<?, ?> properties) {
image = new BufferedImage(cm, raster, isRasterPremultiplied, properties);
}

View File

@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.SWFBundle;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.RenameType;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.configuration.ConfigurationItem;
@@ -67,6 +68,7 @@ import com.jpexs.decompiler.flash.exporters.swf.SwfJavaExporter;
import com.jpexs.decompiler.flash.exporters.swf.SwfXmlExporter;
import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel;
import com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane;
import com.jpexs.decompiler.flash.gui.abc.DeobfuscationDialog;
import com.jpexs.decompiler.flash.gui.action.ActionPanel;
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
@@ -742,13 +744,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
}
showDetail(DETAILCARDEMPTYPANEL);
showCard(CARDEMPTYPANEL);
swfs.add(newSwfs);
SWF swf = newSwfs.size() > 0 ? newSwfs.get(0) : null;
if (swf != null) {
updateUi(swf);
}
reload(false);
}
private ABCPanel getABCPanel() {
@@ -946,9 +948,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
public void renameMultiname(List<ABCContainerTag> abcList, int multiNameIndex) {
String oldName = "";
if (getABCPanel().abc.constants.getMultiname(multiNameIndex).name_index > 0) {
oldName = getABCPanel().abc.constants.getString(getABCPanel().abc.constants.getMultiname(multiNameIndex).name_index);
AVM2ConstantPool constants = getABCPanel().abc.constants;
if (constants.getMultiname(multiNameIndex).name_index > 0) {
oldName = constants.getString(constants.getMultiname(multiNameIndex).name_index);
}
String newName = View.showInputDialog(translate("rename.enternew"), oldName);
if (newName != null) {
if (!oldName.equals(newName)) {
@@ -967,13 +971,16 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
}
}
View.showMessageDialog(null, translate("rename.finished.multiname").replace("%count%", Integer.toString(mulCount)));
if (abcPanel != null) {
abcPanel.reload();
}
updateClassesList();
reload(true);
getABCPanel().hilightScript(getABCPanel().getSwf(), getABCPanel().decompiledTextArea.getScriptLeaf().getClassPath().toString());
ABCPanel abcPanel = getABCPanel();
abcPanel.hilightScript(abcPanel.getSwf(), abcPanel.decompiledTextArea.getScriptLeaf().getClassPath().toString());
}
}
}
@@ -1354,14 +1361,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (swf == null) {
return;
}
String documentClass = swf.getDocumentClass();
if (documentClass != null && !Configuration.dumpView.get()) {
List<ABCContainerTag> abcList = swf.getAbcList();
if (!abcList.isEmpty()) {
getABCPanel().setAbc(abcList.get(0).getABC());
getABCPanel().hilightScript(swf, documentClass);
showDetail(DETAILCARDAS3NAVIGATOR);
showCard(CARDACTIONSCRIPT3PANEL);
ABCPanel abcPanel = getABCPanel();
abcPanel.setAbc(abcList.get(0).getABC());
abcPanel.hilightScript(swf, documentClass);
}
}
}
@@ -1958,17 +1965,19 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
new CancellableWorker() {
@Override
protected Object doInBackground() throws Exception {
int cnt = 0;
ABCPanel abcPanel = getABCPanel();
if (all) {
for (ABCContainerTag tag : getABCPanel().getAbcList()) {
for (ABCContainerTag tag : abcPanel.getAbcList()) {
tag.getABC().restoreControlFlow();
}
} else {
int bi = getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex();
ABC abc = abcPanel.abc;
int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex();
if (bi != -1) {
getABCPanel().abc.bodies.get(bi).restoreControlFlow(getABCPanel().abc.constants, getABCPanel().decompiledTextArea.getCurrentTrait(), getABCPanel().abc.method_info.get(getABCPanel().abc.bodies.get(bi).method_info));
abc.bodies.get(bi).restoreControlFlow(abc.constants, abcPanel.decompiledTextArea.getCurrentTrait(), abc.method_info.get(abc.bodies.get(bi).method_info));
}
getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, getABCPanel().abc, getABCPanel().decompiledTextArea.getCurrentTrait(), getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getScriptIndex());
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, abcPanel.decompiledTextArea.getCurrentTrait(), abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getScriptIndex());
}
return true;
}
@@ -2037,8 +2046,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
@Override
protected Object doInBackground() throws Exception {
try {
ABCPanel aBCPanel = getABCPanel();
if (deobfuscationDialog.processAllCheckbox.isSelected()) {
for (ABCContainerTag tag : getABCPanel().getAbcList()) {
for (ABCContainerTag tag : abcPanel.getAbcList()) {
if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) {
tag.getABC().removeDeadCode();
} else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) {
@@ -2049,19 +2059,22 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
}
} else {
int bi = getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex();
Trait t = getABCPanel().decompiledTextArea.getCurrentTrait();
int bi = abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex();
DecompiledEditorPane decompiledTextArea = abcPanel.decompiledTextArea;
Trait t = abcPanel.decompiledTextArea.getCurrentTrait();
ABC abc = abcPanel.abc;
if (bi != -1) {
if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_DEAD_CODE) {
getABCPanel().abc.bodies.get(bi).removeDeadCode(getABCPanel().abc.constants, t, getABCPanel().abc.method_info.get(getABCPanel().abc.bodies.get(bi).method_info));
abc.bodies.get(bi).removeDeadCode(abc.constants, t, abc.method_info.get(abc.bodies.get(bi).method_info));
} else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_REMOVE_TRAPS) {
getABCPanel().abc.bodies.get(bi).removeTraps(getABCPanel().abc.constants, getABCPanel().abc, t, getABCPanel().decompiledTextArea.getScriptLeaf().scriptIndex, getABCPanel().decompiledTextArea.getClassIndex(), getABCPanel().decompiledTextArea.getIsStatic(), ""/*FIXME*/);
abc.bodies.get(bi).removeTraps(abc.constants, abc, t, decompiledTextArea.getScriptLeaf().scriptIndex, decompiledTextArea.getClassIndex(), decompiledTextArea.getIsStatic(), ""/*FIXME*/);
} else if (deobfuscationDialog.codeProcessingLevel.getValue() == DeobfuscationDialog.LEVEL_RESTORE_CONTROL_FLOW) {
getABCPanel().abc.bodies.get(bi).removeTraps(getABCPanel().abc.constants, getABCPanel().abc, t, getABCPanel().decompiledTextArea.getScriptLeaf().scriptIndex, getABCPanel().decompiledTextArea.getClassIndex(), getABCPanel().decompiledTextArea.getIsStatic(), ""/*FIXME*/);
getABCPanel().abc.bodies.get(bi).restoreControlFlow(getABCPanel().abc.constants, t, getABCPanel().abc.method_info.get(getABCPanel().abc.bodies.get(bi).method_info));
abc.bodies.get(bi).removeTraps(abc.constants, abc, t, decompiledTextArea.getScriptLeaf().scriptIndex, decompiledTextArea.getClassIndex(), decompiledTextArea.getIsStatic(), ""/*FIXME*/);
abc.bodies.get(bi).restoreControlFlow(abc.constants, t, abc.method_info.get(abc.bodies.get(bi).method_info));
}
}
getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, getABCPanel().abc, t, getABCPanel().detailPanel.methodTraitPanel.methodCodePanel.getScriptIndex());
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, t, abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getScriptIndex());
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Deobfuscation error", ex);
@@ -2144,6 +2157,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (abcPanel != null) {
abcPanel.reload();
}
reload(true);
updateClassesList();
}
@@ -2266,12 +2280,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (selfile.getName().toLowerCase().endsWith(".mp3")) {
soundFormat = SoundFormat.FORMAT_MP3;
}
boolean ok = false;
try {
ok = ds.setSound(new FileInputStream(selfile), soundFormat);
} catch (IOException ex) {
//ignore
}
if (!ok) {
View.showMessageDialog(null, translate("error.sound.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE);
} else {
@@ -2298,6 +2314,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
logger.log(Level.SEVERE, "Invalid image", ex);
View.showMessageDialog(null, translate("error.image.invalid"), translate("error"), JOptionPane.ERROR_MESSAGE);
}
reload(true);
}
}
@@ -2315,6 +2332,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
refreshTree(swf);
setTagTreeSelectedNode(newTag);
}
swf.clearImageCache();
} catch (IOException ex) {
logger.log(Level.SEVERE, "Invalid image", ex);
@@ -2422,7 +2440,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
return null;
}
public void showDetail(String card) {
private void showDetail(String card) {
CardLayout cl = (CardLayout) (detailPanel.getLayout());
cl.show(detailPanel, card);
if (card.equals(DETAILCARDEMPTYPANEL)) {
@@ -2437,7 +2455,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
public void showCard(String card) {
private void showCard(String card) {
CardLayout cl = (CardLayout) (displayPanel.getLayout());
cl.show(displayPanel, card);
}
@@ -2656,12 +2674,22 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
preferScript = true;
}
//if (flashPanel != null) {
// flashPanel.specialPlayback = false;
//}
folderPreviewPanel.setItems(new ArrayList<>());
previewPanel.clear();
stopFlashPlayer();
previewPanel.setImageReplaceButtonVisible(false);
/*if (treeItem instanceof Tag) {
Tag tag = (Tag) treeItem;
Set<Integer> needed = new HashSet<>();
tag.getNeededCharactersDeep(needed);
String neededStr = Helper.joinStrings(needed, ", ");
// todo: it would be usefule to show this information on the UI
System.out.println("Needed characters: " + neededStr);
}*/
boolean internalViewer = isInternalFlashViewerSelected();
if (treeItem instanceof ScriptPack) {
final ScriptPack scriptLeaf = (ScriptPack) treeItem;
if (setSourceWorker != null) {
@@ -2706,28 +2734,14 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
showDetail(DETAILCARDAS3NAVIGATOR);
showCard(CARDACTIONSCRIPT3PANEL);
return;
} else {
showDetail(DETAILCARDEMPTYPANEL);
}
previewPanel.setImageReplaceButtonVisible(false);
/*if (treeItem instanceof Tag) {
Tag tag = (Tag) treeItem;
Set<Integer> needed = new HashSet<>();
tag.getNeededCharactersDeep(needed);
String neededStr = Helper.joinStrings(needed, ", ");
// todo: it would be usefule to show this information on the UI
System.out.println("Needed characters: " + neededStr);
}*/
boolean internalViewer = isInternalFlashViewerSelected();
showDetail(DETAILCARDEMPTYPANEL);
if (treeItem instanceof HeaderItem) {
headerPanel.load(((HeaderItem) treeItem).getSwf());
showCard(CARDHEADER);
} else if (treeItem instanceof FolderItem) {
showFolderPreview(treeItem);
showCard(CARDFOLDERPREVIEWPANEL);
showFolderPreview((FolderItem) treeItem);
} else if (treeItem instanceof SWF) {
SWF swf = (SWF) treeItem;
if (internalViewer) {
@@ -2771,13 +2785,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
previewPanel.showImagePanel(timelined, tag.getSwf(), -1);
showCard(CARDPREVIEWPANEL);
} else if ((treeItem instanceof FontTag) && internalViewer) {
FontTag fontTag = (FontTag) treeItem;
showFontTag(fontTag);
showCard(CARDPREVIEWPANEL);
showFontTag((FontTag) treeItem);
} else if ((treeItem instanceof TextTag) && internalViewer) {
TextTag textTag = (TextTag) treeItem;
showTextTag(textTag);
showCard(CARDPREVIEWPANEL);
showTextTag((TextTag) treeItem);
} else if (treeItem instanceof Frame && internalViewer) {
Frame fn = (Frame) treeItem;
SWF swf = fn.getSwf();
@@ -2840,11 +2850,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
private void showFontTag(FontTag ft) {
previewPanel.showFontPanel(ft);
showCard(CARDPREVIEWPANEL);
}
private void showTextTag(TextTag textTag) {
previewPanel.showTextPanel(textTag);
showCard(CARDPREVIEWPANEL);
}
public void showTextTagWithNewValue(TextTag textTag, TextTag newTextTag) {
@@ -2852,9 +2864,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
previewPanel.showTextComparePanel(textTag, newTextTag);
}
private void showFolderPreview(TreeItem treeNode) {
private void showFolderPreview(FolderItem item) {
List<TreeItem> folderPreviewItems = new ArrayList<>();
FolderItem item = (FolderItem) treeNode;
String folderName = item.getName();
SWF swf = item.swf;
switch (folderName) {
@@ -2913,7 +2924,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
}
break;
}
folderPreviewPanel.setItems(folderPreviewItems);
showCard(CARDFOLDERPREVIEWPANEL);
}
private boolean isFreeing;

File diff suppressed because it is too large Load Diff