mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 17:38:17 +00:00
allow to specify tag type on image and shape import
This commit is contained in:
@@ -21,10 +21,13 @@ import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -36,7 +39,10 @@ import java.io.IOException;
|
||||
public class ImageImporter extends TagImporter {
|
||||
|
||||
public Tag importImage(ImageTag it, byte[] newData) throws IOException {
|
||||
return importImage(it, newData, 0);
|
||||
}
|
||||
|
||||
public Tag importImage(ImageTag it, byte[] newData, int tagType) throws IOException {
|
||||
if (newData[0] == 'B' && newData[1] == 'M') {
|
||||
BufferedImage b = ImageHelper.read(newData);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
@@ -44,16 +50,56 @@ public class ImageImporter extends TagImporter {
|
||||
newData = baos.toByteArray();
|
||||
}
|
||||
|
||||
if (it instanceof DefineBitsTag) {
|
||||
SWF swf = it.getSwf();
|
||||
DefineBitsJPEG2Tag jpeg2Tag = new DefineBitsJPEG2Tag(swf, it.getOriginalRange(), it.getCharacterId(), newData);
|
||||
jpeg2Tag.setModified(true);
|
||||
swf.tags.set(swf.tags.indexOf(it), jpeg2Tag);
|
||||
swf.updateCharacters();
|
||||
return jpeg2Tag;
|
||||
} else {
|
||||
it.setImage(newData);
|
||||
if (tagType == 0) {
|
||||
if (it instanceof DefineBitsTag) {
|
||||
tagType = DefineBitsTag.ID;
|
||||
} else {
|
||||
tagType = it.getId();
|
||||
}
|
||||
}
|
||||
|
||||
if (it.getId() == tagType) {
|
||||
it.setImage(newData);
|
||||
} else {
|
||||
SWF swf = it.getSwf();
|
||||
ImageTag imageTag;
|
||||
ByteArrayRange range = it.getOriginalRange();
|
||||
int characterId = it.getCharacterId();
|
||||
switch (tagType) {
|
||||
case DefineBitsJPEG2Tag.ID: {
|
||||
imageTag = new DefineBitsJPEG2Tag(swf, range, characterId, newData);
|
||||
break;
|
||||
}
|
||||
case DefineBitsJPEG3Tag.ID: {
|
||||
imageTag = new DefineBitsJPEG3Tag(swf, range, characterId, newData);
|
||||
break;
|
||||
}
|
||||
case DefineBitsJPEG4Tag.ID: {
|
||||
imageTag = new DefineBitsJPEG4Tag(swf, range, characterId, newData);
|
||||
break;
|
||||
}
|
||||
case DefineBitsLosslessTag.ID: {
|
||||
DefineBitsLosslessTag losslessTag = new DefineBitsLosslessTag(swf, range, characterId);
|
||||
losslessTag.setImage(newData);
|
||||
imageTag = losslessTag;
|
||||
break;
|
||||
}
|
||||
case DefineBitsLossless2Tag.ID: {
|
||||
DefineBitsLossless2Tag lossless2Tag = new DefineBitsLossless2Tag(swf, range, characterId);
|
||||
lossless2Tag.setImage(newData);
|
||||
imageTag = lossless2Tag;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error("Unsupported image type tag.");
|
||||
}
|
||||
|
||||
imageTag.setModified(true);
|
||||
swf.tags.set(swf.tags.indexOf(it), imageTag);
|
||||
swf.updateCharacters();
|
||||
return imageTag;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,10 @@ package com.jpexs.decompiler.flash.importers;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.helpers.ImageHelper;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
@@ -36,6 +39,10 @@ import java.io.IOException;
|
||||
public class ShapeImporter {
|
||||
|
||||
public Tag importImage(ShapeTag st, byte[] newData) throws IOException {
|
||||
return importImage(st, newData, 0);
|
||||
}
|
||||
|
||||
public Tag importImage(ShapeTag st, byte[] newData, int tagType) throws IOException {
|
||||
SWF swf = st.getSwf();
|
||||
|
||||
if (newData[0] == 'B' && newData[1] == 'M') {
|
||||
@@ -45,14 +52,42 @@ public class ShapeImporter {
|
||||
newData = baos.toByteArray();
|
||||
}
|
||||
|
||||
if (tagType == 0) {
|
||||
if (ImageTag.getImageFormat(newData) == ImageFormat.JPEG) {
|
||||
tagType = DefineBitsJPEG2Tag.ID;
|
||||
} else {
|
||||
tagType = DefineBitsLossless2Tag.ID;
|
||||
}
|
||||
}
|
||||
|
||||
ImageTag imageTag;
|
||||
if (ImageTag.getImageFormat(newData) == ImageFormat.JPEG) {
|
||||
DefineBitsJPEG2Tag jpeg2Tag = new DefineBitsJPEG2Tag(swf, null, swf.getNextCharacterId(), newData);
|
||||
imageTag = jpeg2Tag;
|
||||
} else {
|
||||
DefineBitsLossless2Tag lossless2Tag = new DefineBitsLossless2Tag(swf);
|
||||
lossless2Tag.setImage(newData);
|
||||
imageTag = lossless2Tag;
|
||||
switch (tagType) {
|
||||
case DefineBitsJPEG2Tag.ID: {
|
||||
imageTag = new DefineBitsJPEG2Tag(swf, null, swf.getNextCharacterId(), newData);
|
||||
break;
|
||||
}
|
||||
case DefineBitsJPEG3Tag.ID: {
|
||||
imageTag = new DefineBitsJPEG3Tag(swf, null, swf.getNextCharacterId(), newData);
|
||||
break;
|
||||
}
|
||||
case DefineBitsJPEG4Tag.ID: {
|
||||
imageTag = new DefineBitsJPEG4Tag(swf, null, swf.getNextCharacterId(), newData);
|
||||
break;
|
||||
}
|
||||
case DefineBitsLosslessTag.ID: {
|
||||
DefineBitsLosslessTag losslessTag = new DefineBitsLosslessTag(swf);
|
||||
losslessTag.setImage(newData);
|
||||
imageTag = losslessTag;
|
||||
break;
|
||||
}
|
||||
case DefineBitsLossless2Tag.ID: {
|
||||
DefineBitsLossless2Tag lossless2Tag = new DefineBitsLossless2Tag(swf);
|
||||
lossless2Tag.setImage(newData);
|
||||
imageTag = lossless2Tag;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error("Unsupported image type tag.");
|
||||
}
|
||||
|
||||
int idx = swf.tags.indexOf(st);
|
||||
|
||||
@@ -67,13 +67,13 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
|
||||
this.imageData = new ByteArrayRange(imageData);
|
||||
}
|
||||
|
||||
private byte[] createEmptyImage() {
|
||||
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
|
||||
ImageHelper.write(img, ImageFormat.JPEG, bitmapDataOS);
|
||||
return bitmapDataOS.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineBitsJPEG2Tag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
@@ -97,6 +97,20 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
|
||||
sos.write(imageData);
|
||||
}
|
||||
|
||||
private byte[] createEmptyImage() {
|
||||
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
|
||||
ImageHelper.write(img, ImageFormat.JPEG, bitmapDataOS);
|
||||
return bitmapDataOS.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
imageData = new ByteArrayRange(data);
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageFormat getImageFormat() {
|
||||
return ImageTag.getImageFormat(imageData);
|
||||
@@ -120,22 +134,15 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = ret;
|
||||
cachedImage = img;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
imageData = new ByteArrayRange(data);
|
||||
clearCache();
|
||||
setModified(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,14 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
|
||||
forceWriteAsLong = true;
|
||||
}
|
||||
|
||||
public DefineBitsJPEG3Tag(SWF swf, ByteArrayRange data, int characterID, byte[] imageData) throws IOException {
|
||||
super(swf, ID, NAME, data);
|
||||
this.characterID = characterID;
|
||||
this.imageData = new ByteArrayRange(imageData);
|
||||
bitmapAlphaData = ByteArrayRange.EMPTY;
|
||||
forceWriteAsLong = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -153,7 +161,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@Override
|
||||
public InputStream getOriginalImageData() {
|
||||
if (bitmapAlphaData.getLength() == 0) { //No alpha, then its JPEG
|
||||
if (bitmapAlphaData.getLength() == 0) { // No alpha
|
||||
int errorLength = hasErrorHeader(imageData) ? 4 : 0;
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,14 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
|
||||
forceWriteAsLong = true;
|
||||
}
|
||||
|
||||
public DefineBitsJPEG4Tag(SWF swf, ByteArrayRange data, int characterID, byte[] imageData) throws IOException {
|
||||
super(swf, ID, NAME, data);
|
||||
this.characterID = characterID;
|
||||
this.imageData = new ByteArrayRange(imageData);
|
||||
bitmapAlphaData = ByteArrayRange.EMPTY;
|
||||
forceWriteAsLong = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -158,7 +166,7 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
|
||||
|
||||
@Override
|
||||
public InputStream getOriginalImageData() {
|
||||
if (bitmapAlphaData.getLength() == 0) { //No alpha, then its JPEG
|
||||
if (bitmapAlphaData.getLength() == 0) { // No alpha
|
||||
return new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength());
|
||||
}
|
||||
|
||||
|
||||
@@ -87,8 +87,12 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsLossless2Tag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
this(swf, null, swf.getNextCharacterId());
|
||||
}
|
||||
|
||||
public DefineBitsLossless2Tag(SWF swf, ByteArrayRange data, int characterID) {
|
||||
super(swf, ID, NAME, data);
|
||||
this.characterID = characterID;
|
||||
bitmapFormat = DefineBitsLossless2Tag.FORMAT_32BIT_ARGB;
|
||||
bitmapWidth = 1;
|
||||
bitmapHeight = 1;
|
||||
@@ -202,11 +206,11 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
|
||||
|
||||
private void uncompressData() {
|
||||
try {
|
||||
SWFInputStream sis = new SWFInputStream(swf, Helper.readStream(new InflaterInputStream(new ByteArrayInputStream(zlibBitmapData.getArray(), zlibBitmapData.getPos(), zlibBitmapData.getLength()))));
|
||||
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.readALPHACOLORMAPDATA(bitmapColorTableSize, bitmapWidth, bitmapHeight, "colorMapData");
|
||||
}
|
||||
if (bitmapFormat == FORMAT_32BIT_ARGB) {
|
||||
} else if (bitmapFormat == FORMAT_32BIT_ARGB) {
|
||||
bitmapData = sis.readALPHABITMAPDATA(bitmapFormat, bitmapWidth, bitmapHeight, "bitmapData");
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -89,8 +89,12 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
|
||||
* @param swf
|
||||
*/
|
||||
public DefineBitsLosslessTag(SWF swf) {
|
||||
super(swf, ID, NAME, null);
|
||||
characterID = swf.getNextCharacterId();
|
||||
this(swf, null, swf.getNextCharacterId());
|
||||
}
|
||||
|
||||
public DefineBitsLosslessTag(SWF swf, ByteArrayRange data, int characterID) {
|
||||
super(swf, ID, NAME, data);
|
||||
this.characterID = characterID;
|
||||
bitmapFormat = DefineBitsLosslessTag.FORMAT_24BIT_RGB;
|
||||
bitmapWidth = 1;
|
||||
bitmapHeight = 1;
|
||||
@@ -181,6 +185,39 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageFormat getImageFormat() {
|
||||
return ImageFormat.PNG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getOriginalImageData() {
|
||||
return null;
|
||||
@@ -238,37 +275,4 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
|
||||
|
||||
return bi;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageFormat getImageFormat() {
|
||||
return ImageFormat.PNG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,13 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
forceWriteAsLong = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param sis
|
||||
* @param data
|
||||
* @throws IOException
|
||||
*/
|
||||
public DefineBitsTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
|
||||
super(sis.getSwf(), ID, NAME, data);
|
||||
readData(sis, data, 0, false, false, false);
|
||||
@@ -83,15 +90,20 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
sos.write(jpegData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
// importing a new image will replace the current DefineBitsTag with a new DefineBitsJPEG2Tag
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(byte[] data) {
|
||||
throw new UnsupportedOperationException("Set image is not supported for DefineBits");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importSupported() {
|
||||
// importing a new image will replace the current DefineBitsTag with a new DefineBitsJPEG2Tag
|
||||
return true;
|
||||
public ImageFormat getImageFormat() {
|
||||
return ImageFormat.JPEG;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -132,12 +144,12 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
SerializableImage ret = new SerializableImage(image);
|
||||
SerializableImage img = new SerializableImage(image);
|
||||
if (Configuration.cacheImages.get()) {
|
||||
cachedImage = ret;
|
||||
cachedImage = img;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return img;
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to get image", ex);
|
||||
}
|
||||
@@ -146,11 +158,6 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageFormat getImageFormat() {
|
||||
return ImageFormat.JPEG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Tag tag) {
|
||||
// cache should be cleared when Jtt tag changes
|
||||
|
||||
Reference in New Issue
Block a user