Workaround for ImageIO jpeg export bug when alpha channel exists, tag method orders changed (contructors, readData, getData, etc)

This commit is contained in:
honfika@gmail.com
2015-05-16 11:04:14 +02:00
parent 7d3373f96e
commit 3632c466e1
43 changed files with 6011 additions and 5832 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.timeline.Timeline;
@@ -355,7 +356,7 @@ public class FrameExporter {
final int fi = i;
new RetryTask(() -> {
File file = new File(foutdir + File.separator + (fframes.get(fi) + 1) + ".png");
ImageHelper.write(frameImages.next(), "PNG", file);
ImageHelper.write(frameImages.next(), ImageFormat.PNG, file);
ret.add(file);
}, handler).run();
}

View File

@@ -25,13 +25,13 @@ import com.jpexs.decompiler.flash.helpers.BMPFile;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
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.Helper;
import com.jpexs.helpers.Path;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
*
@@ -68,28 +68,28 @@ public class ImageExporter {
final ImageTag imageTag = (ImageTag) t;
String fileFormat = imageTag.getImageFormat().toUpperCase(Locale.ENGLISH);
ImageFormat fileFormat = imageTag.getImageFormat();
if (settings.mode == ImageExportMode.PNG) {
fileFormat = "png";
fileFormat = ImageFormat.PNG;
}
if (settings.mode == ImageExportMode.JPEG) {
fileFormat = "jpg";
fileFormat = ImageFormat.JPEG;
}
if (settings.mode == ImageExportMode.BMP) {
fileFormat = "bmp";
fileFormat = ImageFormat.BMP;
}
{
final File file = new File(outdir + File.separator + Helper.makeFileName(imageTag.getCharacterExportFileName() + "." + fileFormat));
final String ffileFormat = fileFormat;
final ImageFormat ffileFormat = fileFormat;
new RetryTask(() -> {
if (ffileFormat.equals("bmp")) {
if (ffileFormat == ImageFormat.BMP) {
BMPFile.saveBitmap(imageTag.getImage().getBufferedImage(), file);
} else {
ImageHelper.write(imageTag.getImage().getBufferedImage(), ffileFormat.toUpperCase(Locale.ENGLISH), file);
ImageHelper.write(imageTag.getImage().getBufferedImage(), ffileFormat, file);
}
}, handler).run();
ret.add(file);

View File

@@ -32,6 +32,7 @@ import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.RenderContext;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPE;
@@ -126,7 +127,7 @@ public class ShapeExporter {
m.scale(settings.zoom);
st.toImage(0, 0, 0, new RenderContext(), img, m, new CXFORMWITHALPHA());
if (settings.mode == ShapeExportMode.PNG) {
ImageHelper.write(img.getBufferedImage(), "PNG", file);
ImageHelper.write(img.getBufferedImage(), ImageFormat.PNG, file);
} else {
BMPFile.saveBitmap(img.getBufferedImage(), file);
}

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
import com.jpexs.decompiler.flash.types.GRADIENT;
@@ -34,7 +35,6 @@ import com.jpexs.helpers.SerializableImage;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Locale;
import org.w3c.dom.Element;
/**
@@ -115,14 +115,14 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter {
int height = img.getHeight();
lastPatternId++;
String patternId = "PatternID_" + lastPatternId;
String format = image.getImageFormat();
ImageFormat format = image.getImageFormat();
InputStream imageStream = image.getImageData();
byte[] imageData;
if (imageStream != null) {
imageData = Helper.readStream(image.getImageData());
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageHelper.write(img.getBufferedImage(), format.toUpperCase(Locale.ENGLISH), baos);
ImageHelper.write(img.getBufferedImage(), format, baos);
imageData = baos.toByteArray();
}
String base64ImgData = Helper.byteArrayToBase64String(imageData);

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
import com.jpexs.decompiler.flash.types.GRADIENT;
@@ -34,7 +35,6 @@ import com.jpexs.helpers.SerializableImage;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Locale;
import org.w3c.dom.Element;
/**
@@ -113,14 +113,14 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter {
lastPatternId++;
String patternId = "PatternID_";
patternId += lastPatternId;
String format = image.getImageFormat();
ImageFormat format = image.getImageFormat();
InputStream imageStream = image.getImageData();
byte[] imageData;
if (imageStream != null) {
imageData = Helper.readStream(image.getImageData());
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageHelper.write(img.getBufferedImage(), format.toUpperCase(Locale.ENGLISH), baos);
ImageHelper.write(img.getBufferedImage(), format, baos);
imageData = baos.toByteArray();
}
String base64ImgData = Helper.byteArrayToBase64String(imageData);

View File

@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.helpers;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -23,6 +25,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
@@ -57,19 +60,67 @@ public class ImageHelper {
return in;
}
public static void write(BufferedImage image, String formatName, File output) throws IOException {
public static void write(BufferedImage image, ImageFormat format, File output) throws IOException {
String formatName = getImageFormatString(format).toUpperCase(Locale.ENGLISH);
if (format == ImageFormat.JPEG) {
image = fixImageIOJpegBug(image);
}
ImageIO.write(image, formatName, output);
}
public static void write(BufferedImage image, String formatName, OutputStream output) throws IOException {
public static void write(BufferedImage image, ImageFormat format, OutputStream output) throws IOException {
String formatName = getImageFormatString(format).toUpperCase(Locale.ENGLISH);
if (format == ImageFormat.JPEG) {
image = fixImageIOJpegBug(image);
}
ImageIO.write(image, formatName, output);
}
public static void write(BufferedImage image, String formatName, ByteArrayOutputStream output) {
public static void write(BufferedImage image, ImageFormat format, ByteArrayOutputStream output) {
String formatName = getImageFormatString(format).toUpperCase(Locale.ENGLISH);
if (format == ImageFormat.JPEG) {
image = fixImageIOJpegBug(image);
}
try {
ImageIO.write(image, formatName, output);
} catch (IOException ex) {
Logger.getLogger(ImageHelper.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static BufferedImage fixImageIOJpegBug(BufferedImage image) {
int type = image.getType();
if (type != BufferedImage.TYPE_INT_RGB) {
// convert to RGB without alpha channel
int width = image.getWidth();
int height = image.getHeight();
int[] imgData = image.getRGB(0, 0, width, height, null, 0, width);
ImageTag.divideAlpha(imgData);
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
newImage.getRaster().setDataElements(0, 0, width, height, imgData);
return newImage;
}
return image;
}
public static String getImageFormatString(ImageFormat format) {
switch (format) {
case UNKNOWN:
return "unk";
case JPEG:
return "jpg";
case GIF:
return "gif";
case PNG:
return "png";
case BMP:
return "bmp";
}
throw new Error("Unsuported image format: " + format);
}
}

View File

@@ -19,9 +19,12 @@ 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.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 java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -37,7 +40,7 @@ public class ImageImporter extends TagImporter {
if (newData[0] == 'B' && newData[1] == 'M') {
BufferedImage b = ImageHelper.read(newData);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageHelper.write(b, "PNG", baos);
ImageHelper.write(b, ImageFormat.PNG, baos);
newData = baos.toByteArray();
}
@@ -53,4 +56,14 @@ public class ImageImporter extends TagImporter {
}
return null;
}
public Tag importImageAlpha(ImageTag it, byte[] newData) throws IOException {
if (it instanceof DefineBitsJPEG3Tag) {
((DefineBitsJPEG3Tag) it).setImageAlpha(newData);
} else if (it instanceof DefineBitsJPEG4Tag) {
((DefineBitsJPEG4Tag) it).setImageAlpha(newData);
}
return null;
}
}

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
@@ -38,7 +39,7 @@ public class ShapeImporter {
if (newData[0] == 'B' && newData[1] == 'M') {
BufferedImage b = ImageHelper.read(newData);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageHelper.write(b, "PNG", baos);
ImageHelper.write(b, ImageFormat.PNG, baos);
newData = baos.toByteArray();
}

View File

@@ -56,26 +56,6 @@ public class DefineBinaryDataTag extends CharacterTag {
@Internal
public SWF innerSwf;
/**
* 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(tag);
sos.writeUI32(reserved);
sos.write(binaryData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -110,6 +90,26 @@ public class DefineBinaryDataTag extends CharacterTag {
}
}
/**
* 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(tag);
sos.writeUI32(reserved);
sos.write(binaryData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return tag;

View File

@@ -22,6 +22,7 @@ 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.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
@@ -92,7 +93,7 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
}
@Override
public String getImageFormat() {
public ImageFormat getImageFormat() {
return ImageTag.getImageFormat(imageData);
}

View File

@@ -22,6 +22,7 @@ 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.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
@@ -109,14 +110,14 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
private byte[] createEmptyImage() {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
ImageHelper.write(img, "JPG", bitmapDataOS);
ImageHelper.write(img, ImageFormat.JPEG, bitmapDataOS);
return bitmapDataOS.toByteArray();
}
@Override
public void setImage(byte[] data) throws IOException {
if (ImageTag.getImageFormat(data).equals("jpg")) {
SerializableImage image = new SerializableImage(ImageHelper.read(data));
if (ImageTag.getImageFormat(data) == ImageFormat.JPEG) {
BufferedImage image = ImageHelper.read(data);
byte[] ba = new byte[image.getWidth() * image.getHeight()];
for (int i = 0; i < ba.length; i++) {
ba[i] = (byte) 255;
@@ -132,11 +133,27 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
setModified(true);
}
public void setImageAlpha(byte[] data) throws IOException {
ImageFormat fmt = ImageTag.getImageFormat(imageData);
if (fmt != ImageFormat.JPEG) {
throw new IOException("Only Jpeg can have alpha channel.");
}
SerializableImage image = getImage();
if (data == null || data.length != image.getWidth() * image.getHeight()) {
throw new IOException("Data length must match the size of the image.");
}
bitmapAlphaData = new ByteArrayRange(SWFOutputStream.compressByteArray(data));
clearCache();
setModified(true);
}
@Override
public String getImageFormat() {
String fmt = ImageTag.getImageFormat(imageData);
if (fmt.equals("jpg")) {
fmt = "png"; //transparency
public ImageFormat getImageFormat() {
ImageFormat fmt = ImageTag.getImageFormat(imageData);
if (fmt == ImageFormat.JPEG) {
fmt = ImageFormat.PNG; //transparency
}
return fmt;
}

View File

@@ -22,6 +22,7 @@ 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.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
@@ -114,14 +115,14 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
private byte[] createEmptyImage() {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
ImageHelper.write(img, "JPG", bitmapDataOS);
ImageHelper.write(img, ImageFormat.JPEG, bitmapDataOS);
return bitmapDataOS.toByteArray();
}
@Override
public void setImage(byte[] data) throws IOException {
if (ImageTag.getImageFormat(data).equals("jpg")) {
SerializableImage image = new SerializableImage(ImageHelper.read(data));
if (ImageTag.getImageFormat(data) == ImageFormat.JPEG) {
BufferedImage image = ImageHelper.read(data);
byte[] ba = new byte[image.getWidth() * image.getHeight()];
for (int i = 0; i < ba.length; i++) {
ba[i] = (byte) 255;
@@ -137,11 +138,27 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
setModified(true);
}
public void setImageAlpha(byte[] data) throws IOException {
ImageFormat fmt = ImageTag.getImageFormat(imageData);
if (fmt != ImageFormat.JPEG) {
throw new IOException("Only Jpeg can have alpha channel.");
}
SerializableImage image = getImage();
if (data == null || data.length != image.getWidth() * image.getHeight()) {
throw new IOException("Data length must match the size of the image.");
}
bitmapAlphaData = new ByteArrayRange(SWFOutputStream.compressByteArray(data));
clearCache();
setModified(true);
}
@Override
public String getImageFormat() {
String fmt = ImageTag.getImageFormat(imageData);
if (fmt.equals("jpg")) {
fmt = "png"; //transparency
public ImageFormat getImageFormat() {
ImageFormat fmt = ImageTag.getImageFormat(imageData);
if (fmt == ImageFormat.JPEG) {
fmt = ImageFormat.PNG; //transparency
}
return fmt;
}

View File

@@ -22,6 +22,7 @@ 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.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
import com.jpexs.decompiler.flash.types.BasicType;
@@ -221,8 +222,8 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
}
@Override
public String getImageFormat() {
return "png";
public ImageFormat getImageFormat() {
return ImageFormat.PNG;
}
@Override

View File

@@ -22,6 +22,7 @@ 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.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.BITMAPDATA;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.COLORMAPDATA;
@@ -271,7 +272,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
}
@Override
public String getImageFormat() {
return "png";
public ImageFormat getImageFormat() {
return ImageFormat.PNG;
}
}

View File

@@ -21,6 +21,7 @@ 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.ImageTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
@@ -46,17 +47,6 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
@SWFType(BasicType.UI8)
public ByteArrayRange jpegData;
@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;
}
/**
* Constructor
*
@@ -99,6 +89,17 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
return baos.toByteArray();
}
@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;
}
@Override
public InputStream getImageData() {
return null;
@@ -137,8 +138,8 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
}
@Override
public String getImageFormat() {
return "jpg";
public ImageFormat getImageFormat() {
return ImageFormat.JPEG;
}
@Override

View File

@@ -90,21 +90,6 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
private static final Cache<DefineButton2Tag, RECT> rectCache = Cache.getInstance(true, true, "rect_button2");
@Override
public int getCharacterId() {
return buttonId;
}
@Override
public void setCharacterId(int characterId) {
this.buttonId = characterId;
}
@Override
public List<BUTTONRECORD> getRecords() {
return characters;
}
/**
* Constructor
*
@@ -178,6 +163,21 @@ public class DefineButton2Tag extends ButtonTag implements ASMSourceContainer {
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return buttonId;
}
@Override
public void setCharacterId(int characterId) {
this.buttonId = characterId;
}
@Override
public List<BUTTONRECORD> getRecords() {
return characters;
}
/**
* Returns all sub-items
*

View File

@@ -43,25 +43,6 @@ public class DefineButtonCxformTag extends Tag implements CharacterIdTag {
public CXFORM buttonColorTransform;
/**
* 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(buttonId);
sos.writeCXFORM(buttonColorTransform);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -90,6 +71,25 @@ public class DefineButtonCxformTag extends Tag implements CharacterIdTag {
buttonColorTransform = sis.readCXFORM("buttonColorTransform");
}
/**
* 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(buttonId);
sos.writeCXFORM(buttonColorTransform);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return buttonId;

View File

@@ -61,50 +61,6 @@ public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
public SOUNDINFO buttonSoundInfo3;
@Override
public int getCharacterId() {
return buttonId;
}
@Override
public void setCharacterId(int characterId) {
this.buttonId = characterId;
}
/**
* 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(buttonId);
sos.writeUI16(buttonSoundChar0);
if (buttonSoundChar0 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo0);
}
sos.writeUI16(buttonSoundChar1);
if (buttonSoundChar1 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo1);
}
sos.writeUI16(buttonSoundChar2);
if (buttonSoundChar2 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo2);
}
sos.writeUI16(buttonSoundChar3);
if (buttonSoundChar3 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo3);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -146,4 +102,48 @@ public class DefineButtonSoundTag extends Tag implements CharacterIdTag {
buttonSoundInfo3 = sis.readSOUNDINFO("buttonSoundInfo3");
}
}
/**
* 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(buttonId);
sos.writeUI16(buttonSoundChar0);
if (buttonSoundChar0 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo0);
}
sos.writeUI16(buttonSoundChar1);
if (buttonSoundChar1 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo1);
}
sos.writeUI16(buttonSoundChar2);
if (buttonSoundChar2 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo2);
}
sos.writeUI16(buttonSoundChar3);
if (buttonSoundChar3 != 0) {
sos.writeSOUNDINFO(buttonSoundInfo3);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return buttonId;
}
@Override
public void setCharacterId(int characterId) {
this.buttonId = characterId;
}
}

View File

@@ -83,16 +83,6 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
@HideInRawEdit
public ByteArrayRange actionBytes;
@Override
public int getCharacterId() {
return buttonId;
}
@Override
public void setCharacterId(int characterId) {
this.buttonId = characterId;
}
private Timeline timeline;
private boolean isSingleFrameInitialized;
@@ -101,11 +91,6 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
private static final Cache<DefineButtonTag, RECT> rectCache = Cache.getInstance(true, true, "rect_button");
@Override
public List<BUTTONRECORD> getRecords() {
return characters;
}
/**
* Constructor
*
@@ -162,6 +147,21 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return buttonId;
}
@Override
public void setCharacterId(int characterId) {
this.buttonId = characterId;
}
@Override
public List<BUTTONRECORD> getRecords() {
return characters;
}
/**
* Converts actions to ASM source
*

View File

@@ -97,114 +97,6 @@ public class DefineFont2Tag extends FontTag {
@Conditional("fontFlagsHasLayout")
public List<KERNINGRECORD> fontKerningTable;
@Override
public boolean isSmall() {
return fontFlagsSmallText;
}
@Override
public int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
}
@Override
public RECT getGlyphBounds(int glyphIndex) {
if (fontFlagsHasLayout) {
return fontBoundsTable.get(glyphIndex);
}
return super.getGlyphBounds(glyphIndex);
}
@Override
public double getGlyphAdvance(int glyphIndex) {
if (fontFlagsHasLayout) {
return fontAdvanceTable.get(glyphIndex);
} else {
return -1;
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
try {
sos.writeUI16(fontId);
sos.writeUB(1, fontFlagsHasLayout ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
sos.writeUB(1, fontFlagsWideOffsets ? 1 : 0);
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
sos.writeUB(1, fontFlagsBold ? 1 : 0);
sos.writeLANGCODE(languageCode);
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
sos.writeUI8(fontNameBytes.length);
sos.write(fontNameBytes);
int numGlyphs = glyphShapeTable.size();
sos.writeUI16(numGlyphs);
List<Long> offsetTable = new ArrayList<>();
ByteArrayOutputStream baosGlyphShapes = new ByteArrayOutputStream();
SWFOutputStream sos3 = new SWFOutputStream(baosGlyphShapes, getVersion());
for (int i = 0; i < numGlyphs; i++) {
offsetTable.add((glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + sos3.getPos());
sos3.writeSHAPE(glyphShapeTable.get(i), 1);
}
byte[] baGlyphShapes = baosGlyphShapes.toByteArray();
for (Long offset : offsetTable) {
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) (long) offset);
}
}
if (numGlyphs > 0) {
long offset = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + baGlyphShapes.length;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) offset);
}
sos.write(baGlyphShapes);
for (int i = 0; i < numGlyphs; i++) {
if (fontFlagsWideCodes) {
sos.writeUI16(codeTable.get(i));
} else {
sos.writeUI8(codeTable.get(i));
}
}
}
if (fontFlagsHasLayout) {
sos.writeSI16(fontAscent);
sos.writeSI16(fontDescent);
sos.writeSI16(fontLeading);
for (int i = 0; i < numGlyphs; i++) {
sos.writeSI16(fontAdvanceTable.get(i));
}
for (int i = 0; i < numGlyphs; i++) {
sos.writeRECT(fontBoundsTable.get(i));
}
sos.writeUI16(fontKerningTable.size());
for (int k = 0; k < fontKerningTable.size(); k++) {
sos.writeKERNINGRECORD(fontKerningTable.get(k), fontFlagsWideCodes);
}
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -302,9 +194,112 @@ public class DefineFont2Tag extends FontTag {
}
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public int getFontId() {
return fontId;
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(baos, getVersion());
try {
sos.writeUI16(fontId);
sos.writeUB(1, fontFlagsHasLayout ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
sos.writeUB(1, fontFlagsWideOffsets ? 1 : 0);
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
sos.writeUB(1, fontFlagsBold ? 1 : 0);
sos.writeLANGCODE(languageCode);
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
sos.writeUI8(fontNameBytes.length);
sos.write(fontNameBytes);
int numGlyphs = glyphShapeTable.size();
sos.writeUI16(numGlyphs);
List<Long> offsetTable = new ArrayList<>();
ByteArrayOutputStream baosGlyphShapes = new ByteArrayOutputStream();
SWFOutputStream sos3 = new SWFOutputStream(baosGlyphShapes, getVersion());
for (int i = 0; i < numGlyphs; i++) {
offsetTable.add((glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + sos3.getPos());
sos3.writeSHAPE(glyphShapeTable.get(i), 1);
}
byte[] baGlyphShapes = baosGlyphShapes.toByteArray();
for (Long offset : offsetTable) {
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) (long) offset);
}
}
if (numGlyphs > 0) {
long offset = (glyphShapeTable.size() + 1/*CodeTableOffset*/) * (fontFlagsWideOffsets ? 4 : 2) + baGlyphShapes.length;
if (fontFlagsWideOffsets) {
sos.writeUI32(offset);
} else {
sos.writeUI16((int) offset);
}
sos.write(baGlyphShapes);
for (int i = 0; i < numGlyphs; i++) {
if (fontFlagsWideCodes) {
sos.writeUI16(codeTable.get(i));
} else {
sos.writeUI8(codeTable.get(i));
}
}
}
if (fontFlagsHasLayout) {
sos.writeSI16(fontAscent);
sos.writeSI16(fontDescent);
sos.writeSI16(fontLeading);
for (int i = 0; i < numGlyphs; i++) {
sos.writeSI16(fontAdvanceTable.get(i));
}
for (int i = 0; i < numGlyphs; i++) {
sos.writeRECT(fontBoundsTable.get(i));
}
sos.writeUI16(fontKerningTable.size());
for (int k = 0; k < fontKerningTable.size(); k++) {
sos.writeKERNINGRECORD(fontKerningTable.get(k), fontFlagsWideCodes);
}
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public boolean isSmall() {
return fontFlagsSmallText;
}
@Override
public int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
}
@Override
public RECT getGlyphBounds(int glyphIndex) {
if (fontFlagsHasLayout) {
return fontBoundsTable.get(glyphIndex);
}
return super.getGlyphBounds(glyphIndex);
}
@Override
public double getGlyphAdvance(int glyphIndex) {
if (fontFlagsHasLayout) {
return fontAdvanceTable.get(glyphIndex);
} else {
return -1;
}
}
@Override

View File

@@ -101,35 +101,6 @@ public class DefineFont3Tag extends FontTag {
@Conditional("fontFlagsHasLayout")
public List<KERNINGRECORD> fontKerningTable;
@Override
public boolean isSmall() {
return fontFlagsSmallText;
}
@Override
public int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
}
@Override
public double getGlyphAdvance(int glyphIndex) {
if (fontFlagsHasLayout && glyphIndex != -1) {
return fontAdvanceTable.get(glyphIndex);
} else {
return -1;
}
}
@Override
public char glyphToChar(int glyphIndex) {
return (char) (int) codeTable.get(glyphIndex);
}
@Override
public int charToGlyph(char c) {
return codeTable.indexOf((int) c);
}
/**
* Constructor
*
@@ -312,8 +283,32 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public int getFontId() {
return fontId;
public boolean isSmall() {
return fontFlagsSmallText;
}
@Override
public int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
}
@Override
public double getGlyphAdvance(int glyphIndex) {
if (fontFlagsHasLayout && glyphIndex != -1) {
return fontAdvanceTable.get(glyphIndex);
} else {
return -1;
}
}
@Override
public char glyphToChar(int glyphIndex) {
return (char) (int) codeTable.get(glyphIndex);
}
@Override
public int charToGlyph(char c) {
return codeTable.indexOf((int) c);
}
@Override

View File

@@ -55,16 +55,6 @@ public class DefineFont4Tag extends CharacterTag {
public byte[] fontData;
@Override
public int getCharacterId() {
return fontID;
}
@Override
public void setCharacterId(int characterId) {
this.fontID = characterId;
}
/**
* Constructor
*
@@ -116,4 +106,14 @@ public class DefineFont4Tag extends CharacterTag {
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return fontID;
}
@Override
public void setCharacterId(int characterId) {
this.fontID = characterId;
}
}

View File

@@ -68,38 +68,6 @@ public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
@SWFType(BasicType.UI16)
public List<Integer> codeTable;
/**
* 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(fontID);
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
sos.writeUI8(fontNameBytes.length);
sos.write(fontNameBytes);
sos.writeUB(2, reserved);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
sos.writeUB(1, fontFlagsBold ? 1 : 0);
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
sos.writeLANGCODE(languageCode);
for (int c : codeTable) {
sos.writeUI16(c);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -148,6 +116,38 @@ public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
}
}
/**
* 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(fontID);
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
sos.writeUI8(fontNameBytes.length);
sos.write(fontNameBytes);
sos.writeUB(2, reserved);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
sos.writeUB(1, fontFlagsBold ? 1 : 0);
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
sos.writeLANGCODE(languageCode);
for (int c : codeTable) {
sos.writeUI16(c);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return fontID;

View File

@@ -65,41 +65,6 @@ public class DefineFontInfoTag extends Tag implements CharacterIdTag {
@SWFType(value = BasicType.UI8, alternateValue = BasicType.UI16, alternateCondition = "fontFlagsWideCodes")
public List<Integer> codeTable;
/**
* 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(fontId);
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
sos.writeUI8(fontNameBytes.length);
sos.write(fontNameBytes);
sos.writeUB(2, reserved);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
sos.writeUB(1, fontFlagsBold ? 1 : 0);
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
for (int code : codeTable) {
if (fontFlagsWideCodes) {
sos.writeUI16(code);
} else {
sos.writeUI8(code);
}
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -149,6 +114,41 @@ public class DefineFontInfoTag extends Tag implements CharacterIdTag {
}
}
/**
* 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(fontId);
byte[] fontNameBytes = Utf8Helper.getBytes(fontName);
sos.writeUI8(fontNameBytes.length);
sos.write(fontNameBytes);
sos.writeUB(2, reserved);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsANSI ? 1 : 0);
sos.writeUB(1, fontFlagsItalic ? 1 : 0);
sos.writeUB(1, fontFlagsBold ? 1 : 0);
sos.writeUB(1, fontFlagsWideCodes ? 1 : 0);
for (int code : codeTable) {
if (fontFlagsWideCodes) {
sos.writeUI16(code);
} else {
sos.writeUI8(code);
}
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return fontId;

View File

@@ -54,6 +54,80 @@ public class DefineFontTag extends FontTag {
@Internal
private DefineFontInfo2Tag fontInfo2Tag = null;
/**
* Constructor
*
* @param swf
*/
public DefineFontTag(SWF swf) {
super(swf, ID, NAME, null);
fontId = swf.getNextCharacterId();
glyphShapeTable = new ArrayList<>();
}
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public DefineFontTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, 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 {
fontId = sis.readUI16("fontId");
glyphShapeTable = new ArrayList<>();
if (sis.available() > 0) {
long pos = sis.getPos();
int firstOffset = sis.readUI16("firstOffset");
int nGlyphs = firstOffset / 2;
long[] offsetTable = new long[nGlyphs];
offsetTable[0] = firstOffset;
for (int i = 1; i < nGlyphs; i++) {
offsetTable[i] = sis.readUI16("offset");
}
for (int i = 0; i < nGlyphs; i++) {
sis.seek(pos + offsetTable[i]);
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
}
}
}
/**
* 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(fontId);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
List<Integer> offsetTable = new ArrayList<>();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
for (SHAPE shape : glyphShapeTable) {
offsetTable.add(glyphShapeTable.size() * 2 + (int) sos2.getPos());
sos2.writeSHAPE(shape, 1);
}
for (int offset : offsetTable) {
sos.writeUI16(offset);
}
sos.write(baos2.toByteArray());
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public boolean isSmall() {
return false;
@@ -112,85 +186,6 @@ public class DefineFontTag extends FontTag {
}
/**
* 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(fontId);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
List<Integer> offsetTable = new ArrayList<>();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
for (SHAPE shape : glyphShapeTable) {
offsetTable.add(glyphShapeTable.size() * 2 + (int) sos2.getPos());
sos2.writeSHAPE(shape, 1);
}
for (int offset : offsetTable) {
sos.writeUI16(offset);
}
sos.write(baos2.toByteArray());
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
* @param swf
*/
public DefineFontTag(SWF swf) {
super(swf, ID, NAME, null);
fontId = swf.getNextCharacterId();
glyphShapeTable = new ArrayList<>();
}
/**
* Constructor
*
* @param sis
* @param data
* @throws IOException
*/
public DefineFontTag(SWFInputStream sis, ByteArrayRange data) throws IOException {
super(sis.getSwf(), ID, NAME, 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 {
fontId = sis.readUI16("fontId");
glyphShapeTable = new ArrayList<>();
if (sis.available() > 0) {
long pos = sis.getPos();
int firstOffset = sis.readUI16("firstOffset");
int nGlyphs = firstOffset / 2;
long[] offsetTable = new long[nGlyphs];
offsetTable[0] = firstOffset;
for (int i = 1; i < nGlyphs; i++) {
offsetTable[i] = sis.readUI16("offset");
}
for (int i = 0; i < nGlyphs; i++) {
sis.seek(pos + offsetTable[i]);
glyphShapeTable.add(sis.readSHAPE(1, false, "shape"));
}
}
}
@Override
public int getFontId() {
return fontId;
}
@Override
public List<SHAPE> getGlyphShapeTable() {
return glyphShapeTable;

View File

@@ -56,40 +56,6 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
public boolean usesScalingStrokes;
/**
* 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.writeRECT(startBounds);
sos.writeRECT(endBounds);
sos.writeRECT(startEdgeBounds);
sos.writeRECT(endEdgeBounds);
sos.writeUB(6, reserved);
sos.writeUB(1, usesNonScalingStrokes ? 1 : 0);
sos.writeUB(1, usesScalingStrokes ? 1 : 0);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
sos2.writeMORPHFILLSTYLEARRAY(morphFillStyles, 2);
sos2.writeMORPHLINESTYLEARRAY(morphLineStyles, 2);
sos2.writeSHAPE(startEdges, 2);
byte[] ba2 = baos2.toByteArray();
sos.writeUI32(ba2.length);
sos.write(ba2);
sos.writeSHAPE(endEdges, 2);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -139,6 +105,40 @@ public class DefineMorphShape2Tag extends MorphShapeTag {
endEdges = sis.readSHAPE(2, true, "endEdges");
}
/**
* 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.writeRECT(startBounds);
sos.writeRECT(endBounds);
sos.writeRECT(startEdgeBounds);
sos.writeRECT(endEdgeBounds);
sos.writeUB(6, reserved);
sos.writeUB(1, usesNonScalingStrokes ? 1 : 0);
sos.writeUB(1, usesScalingStrokes ? 1 : 0);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
sos2.writeMORPHFILLSTYLEARRAY(morphFillStyles, 2);
sos2.writeMORPHLINESTYLEARRAY(morphLineStyles, 2);
sos2.writeSHAPE(startEdges, 2);
byte[] ba2 = baos2.toByteArray();
sos.writeUI32(ba2.length);
sos.write(ba2);
sos.writeSHAPE(endEdges, 2);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getShapeNum() {
return 2;

View File

@@ -41,35 +41,6 @@ public class DefineMorphShapeTag extends MorphShapeTag {
public static final String NAME = "DefineMorphShape";
/**
* 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.writeRECT(startBounds);
sos.writeRECT(endBounds);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
sos2.writeMORPHFILLSTYLEARRAY(morphFillStyles, 1);
sos2.writeMORPHLINESTYLEARRAY(morphLineStyles, 1);
sos2.writeSHAPE(startEdges, 1);
byte[] ba2 = baos2.toByteArray();
sos.writeUI32(ba2.length);
sos.write(ba2);
sos.writeSHAPE(endEdges, 1);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -112,6 +83,35 @@ public class DefineMorphShapeTag extends MorphShapeTag {
endEdges = sis.readSHAPE(1, true, "endEdges");
}
/**
* 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.writeRECT(startBounds);
sos.writeRECT(endBounds);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(baos2, getVersion());
sos2.writeMORPHFILLSTYLEARRAY(morphFillStyles, 1);
sos2.writeMORPHLINESTYLEARRAY(morphLineStyles, 1);
sos2.writeSHAPE(startEdges, 1);
byte[] ba2 = baos2.toByteArray();
sos.writeUI32(ba2.length);
sos.write(ba2);
sos.writeSHAPE(endEdges, 1);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getShapeNum() {
return 1;

View File

@@ -51,35 +51,6 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
@SWFArray(countField = "frameLabelCount")
public String[] frameNames;
/**
* 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 {
int sceneCount = sceneOffsets.length;
sos.writeEncodedU32(sceneCount);
for (int i = 0; i < sceneCount; i++) {
sos.writeEncodedU32(sceneOffsets[i]);
sos.writeString(sceneNames[i]);
}
int frameLabelCount = frameNums.length;
sos.writeEncodedU32(frameLabelCount);
for (int i = 0; i < frameLabelCount; i++) {
sos.writeEncodedU32(frameNums[i]);
sos.writeString(frameNames[i]);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -123,4 +94,33 @@ public class DefineSceneAndFrameLabelDataTag extends Tag {
}
}
/**
* 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 {
int sceneCount = sceneOffsets.length;
sos.writeEncodedU32(sceneCount);
for (int i = 0; i < sceneCount; i++) {
sos.writeEncodedU32(sceneOffsets[i]);
sos.writeString(sceneNames[i]);
}
int frameLabelCount = frameNums.length;
sos.writeEncodedU32(frameLabelCount);
for (int i = 0; i < frameLabelCount; i++) {
sos.writeEncodedU32(frameNums[i]);
sos.writeString(frameNames[i]);
}
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
}

View File

@@ -69,41 +69,6 @@ public class DefineSoundTag extends CharacterTag implements SoundTag {
public ByteArrayRange soundData;
@Override
public int getCharacterId() {
return soundId;
}
@Override
public void setCharacterId(int characterId) {
this.soundId = characterId;
}
/**
* 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(soundId);
sos.writeUB(4, soundFormat);
sos.writeUB(2, soundRate);
sos.writeUB(1, soundSize ? 1 : 0);
sos.writeUB(1, soundType ? 1 : 0);
sos.writeUI32(soundSampleCount);
sos.write(soundData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
/**
* Constructor
*
@@ -138,6 +103,41 @@ public class DefineSoundTag extends CharacterTag implements SoundTag {
soundData = sis.readByteRangeEx(sis.available(), "soundData");
}
/**
* 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(soundId);
sos.writeUB(4, soundFormat);
sos.writeUB(2, soundRate);
sos.writeUB(1, soundSize ? 1 : 0);
sos.writeUB(1, soundType ? 1 : 0);
sos.writeUI32(soundSampleCount);
sos.write(soundData);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public int getCharacterId() {
return soundId;
}
@Override
public void setCharacterId(int characterId) {
this.soundId = characterId;
}
@Override
public String getExportFormat() {
if (soundFormat == SoundFormat.FORMAT_MP3) {

View File

@@ -89,6 +89,72 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
private static final Cache<DefineSpriteTag, RECT> rectCache = Cache.getInstance(true, true, "rect_sprite");
/**
* Constructor
*
* @param swf
*/
public DefineSpriteTag(SWF swf) {
super(swf, ID, NAME, null);
spriteId = swf.getNextCharacterId();
subTags = new ArrayList<>();
}
/**
* Constructor
*
* @param sis
* @param data
* @param level
* @param parallel
* @param skipUnusualTags
* @throws IOException
* @throws java.lang.InterruptedException
*/
public DefineSpriteTag(SWFInputStream sis, int level, ByteArrayRange data, boolean parallel, boolean skipUnusualTags) throws IOException, InterruptedException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, level, parallel, skipUnusualTags, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException, InterruptedException {
spriteId = sis.readUI16("spriteId");
frameCount = sis.readUI16("frameCount");
List<Tag> subTags = sis.readTagList(this, level + 1, parallel, skipUnusualTags, true, lazy);
if (subTags.size() > 0 && subTags.get(subTags.size() - 1).getId() == EndTag.ID) {
hasEndTag = true;
subTags.remove(subTags.size() - 1);
}
this.subTags = subTags;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(spriteId);
sos.writeUI16(frameCount);
sos.writeTags(subTags);
if (hasEndTag) {
sos.writeUI16(0);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public Timeline getTimeline() {
if (timeline == null) {
@@ -210,72 +276,6 @@ public class DefineSpriteTag extends CharacterTag implements DrawableTag, Timeli
return ret;
}
/**
* Constructor
*
* @param swf
*/
public DefineSpriteTag(SWF swf) {
super(swf, ID, NAME, null);
spriteId = swf.getNextCharacterId();
subTags = new ArrayList<>();
}
/**
* Constructor
*
* @param sis
* @param data
* @param level
* @param parallel
* @param skipUnusualTags
* @throws IOException
* @throws java.lang.InterruptedException
*/
public DefineSpriteTag(SWFInputStream sis, int level, ByteArrayRange data, boolean parallel, boolean skipUnusualTags) throws IOException, InterruptedException {
super(sis.getSwf(), ID, NAME, data);
readData(sis, data, level, parallel, skipUnusualTags, false);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException, InterruptedException {
spriteId = sis.readUI16("spriteId");
frameCount = sis.readUI16("frameCount");
List<Tag> subTags = sis.readTagList(this, level + 1, parallel, skipUnusualTags, true, lazy);
if (subTags.size() > 0 && subTags.get(subTags.size() - 1).getId() == EndTag.ID) {
hasEndTag = true;
subTags.remove(subTags.size() - 1);
}
this.subTags = subTags;
}
/**
* Gets data bytes
*
* @return Bytes of data
*/
@Override
public byte[] getData() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = baos;
if (Configuration.debugCopy.get()) {
os = new CopyOutputStream(os, new ByteArrayInputStream(getOriginalData()));
}
SWFOutputStream sos = new SWFOutputStream(os, getVersion());
try {
sos.writeUI16(spriteId);
sos.writeUI16(frameCount);
sos.writeTags(subTags);
if (hasEndTag) {
sos.writeUI16(0);
}
sos.close();
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
public List<Tag> getSubTags() {
return subTags;
}

View File

@@ -57,8 +57,6 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
super(swf, id, name, data);
}
public abstract int getFontId();
public abstract List<SHAPE> getGlyphShapeTable();
public abstract void addCharacter(char character, Font font);
@@ -131,6 +129,10 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
reload();
}
public int getFontId() {
return getCharacterId();
}
public boolean hasLayout() {
return false;
}

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter;
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
@@ -65,34 +66,34 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
public abstract void setImage(byte[] data) throws IOException;
public abstract String getImageFormat();
public abstract ImageFormat getImageFormat();
public boolean importSupported() {
return true;
}
public static String getImageFormat(byte[] data) {
public static ImageFormat getImageFormat(byte[] data) {
return getImageFormat(new ByteArrayRange(data));
}
public static String getImageFormat(ByteArrayRange data) {
public static ImageFormat getImageFormat(ByteArrayRange data) {
if (hasErrorHeader(data)) {
return "jpg";
return ImageFormat.JPEG;
}
if (data.getLength() > 2 && ((data.get(0) & 0xff) == 0xff) && ((data.get(1) & 0xff) == 0xd8)) {
return "jpg";
return ImageFormat.JPEG;
}
if (data.getLength() > 6 && ((data.get(0) & 0xff) == 0x47) && ((data.get(1) & 0xff) == 0x49) && ((data.get(2) & 0xff) == 0x46) && ((data.get(3) & 0xff) == 0x38) && ((data.get(4) & 0xff) == 0x39) && ((data.get(5) & 0xff) == 0x61)) {
return "gif";
return ImageFormat.GIF;
}
if (data.getLength() > 8 && ((data.get(0) & 0xff) == 0x89) && ((data.get(1) & 0xff) == 0x50) && ((data.get(2) & 0xff) == 0x4e) && ((data.get(3) & 0xff) == 0x47) && ((data.get(4) & 0xff) == 0x0d) && ((data.get(5) & 0xff) == 0x0a) && ((data.get(6) & 0xff) == 0x1a) && ((data.get(7) & 0xff) == 0x0a)) {
return "png";
return ImageFormat.PNG;
}
return "unk";
return ImageFormat.UNKNOWN;
}
public static boolean hasErrorHeader(byte[] data) {
@@ -128,6 +129,24 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag {
return RGBA.toInt(r, g, b, a);
}
public static void divideAlpha(int[] pixels) {
for (int i = 0; i < pixels.length; i++) {
pixels[i] = divideAlpha(pixels[i]) & 0xffffff;
}
}
protected static int divideAlpha(int value) {
int a = (value >> 24) & 0xFF;
int r = (value >> 16) & 0xFF;
int g = (value >> 8) & 0xFF;
int b = value & 0xFF;
float multiplier = a / 255.0f;
r = max255(r * multiplier);
g = max255(g * multiplier);
b = max255(b * multiplier);
return RGBA.toInt(r, g, b, a);
}
private SHAPEWITHSTYLE getShape() {
RECT rect = getRect();
return getShape(rect, false);

View File

@@ -78,6 +78,61 @@ public abstract class StaticTextTag extends TextTag {
super(swf, id, name, data);
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterID = sis.readUI16("characterID");
textBounds = sis.readRECT("textBounds");
textMatrix = sis.readMatrix("textMatrix");
glyphBits = sis.readUI8("glyphBits");
advanceBits = sis.readUI8("advanceBits");
textRecords = new ArrayList<>();
TEXTRECORD tr;
while ((tr = sis.readTEXTRECORD(getTextNum(), glyphBits, advanceBits, "record")) != null) {
textRecords.add(tr);
}
}
/**
* 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.writeRECT(textBounds);
sos.writeMatrix(textMatrix);
int glyphBits = 0;
int advanceBits = 0;
for (TEXTRECORD tr : textRecords) {
for (GLYPHENTRY ge : tr.glyphEntries) {
glyphBits = SWFOutputStream.enlargeBitCountU(glyphBits, ge.glyphIndex);
advanceBits = SWFOutputStream.enlargeBitCountS(advanceBits, ge.glyphAdvance);
}
}
if (Configuration.debugCopy.get()) {
glyphBits = Math.max(glyphBits, this.glyphBits);
advanceBits = Math.max(advanceBits, this.advanceBits);
}
sos.writeUI8(glyphBits);
sos.writeUI8(advanceBits);
for (TEXTRECORD tr : textRecords) {
sos.writeTEXTRECORD(tr, getTextNum(), glyphBits, advanceBits);
}
sos.writeUI8(0);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public RECT getBounds() {
return textBounds;
@@ -522,61 +577,6 @@ public abstract class StaticTextTag extends TextTag {
return 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.writeRECT(textBounds);
sos.writeMatrix(textMatrix);
int glyphBits = 0;
int advanceBits = 0;
for (TEXTRECORD tr : textRecords) {
for (GLYPHENTRY ge : tr.glyphEntries) {
glyphBits = SWFOutputStream.enlargeBitCountU(glyphBits, ge.glyphIndex);
advanceBits = SWFOutputStream.enlargeBitCountS(advanceBits, ge.glyphAdvance);
}
}
if (Configuration.debugCopy.get()) {
glyphBits = Math.max(glyphBits, this.glyphBits);
advanceBits = Math.max(advanceBits, this.advanceBits);
}
sos.writeUI8(glyphBits);
sos.writeUI8(advanceBits);
for (TEXTRECORD tr : textRecords) {
sos.writeTEXTRECORD(tr, getTextNum(), glyphBits, advanceBits);
}
sos.writeUI8(0);
} catch (IOException e) {
throw new Error("This should never happen.", e);
}
return baos.toByteArray();
}
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
characterID = sis.readUI16("characterID");
textBounds = sis.readRECT("textBounds");
textMatrix = sis.readMatrix("textMatrix");
glyphBits = sis.readUI8("glyphBits");
advanceBits = sis.readUI8("advanceBits");
textRecords = new ArrayList<>();
TEXTRECORD tr;
while ((tr = sis.readTEXTRECORD(getTextNum(), glyphBits, advanceBits, "record")) != null) {
textRecords.add(tr);
}
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
for (TEXTRECORD tr : textRecords) {

View File

@@ -0,0 +1,26 @@
/*
* 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.enums;
/**
*
* @author JPEXS
*/
public enum ImageFormat {
UNKNOWN, JPEG, GIF, PNG, BMP
}

View File

@@ -154,11 +154,6 @@ public final class DefineCompactedFont extends FontTag {
this.fontId = characterId;
}
@Override
public int getFontId() {
return fontId;
}
@Override
public List<SHAPE> getGlyphShapeTable() {
return shapeCache;

View File

@@ -66,6 +66,7 @@ import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import com.jpexs.decompiler.flash.tags.font.CharacterRanges;
import com.jpexs.decompiler.flash.types.BUTTONCONDACTION;
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
@@ -1357,17 +1358,17 @@ public class XFLConverter {
SerializableImage image = imageTag.getImage();
// do not store the image in cache during xfl conversion
imageTag.clearCache();
String format = imageTag.getImageFormat();
ImageHelper.write(image.getBufferedImage(), format.toUpperCase(), baos);
ImageFormat format = imageTag.getImageFormat();
ImageHelper.write(image.getBufferedImage(), format, baos);
String symbolFile = "bitmap" + symbol.getCharacterId() + "." + imageTag.getImageFormat();
files.put(symbolFile, baos.toByteArray());
String mediaLinkStr = "<DOMBitmapItem name=\"" + symbolFile + "\" sourceLastImported=\"" + getTimestamp() + "\" externalFileSize=\"" + baos.toByteArray().length + "\"";
switch (format) {
case "png":
case "gif":
case PNG:
case GIF:
mediaLinkStr += " useImportedJPEGData=\"false\" compressionType=\"lossless\" originalCompressionType=\"lossless\"";
break;
case "jpg":
case JPEG:
mediaLinkStr += " isJPEG=\"true\"";
break;
}

View File

@@ -17,6 +17,7 @@
package com.jpexs.helpers;
import com.jpexs.decompiler.flash.helpers.ImageHelper;
import com.jpexs.decompiler.flash.tags.enums.ImageFormat;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
@@ -144,7 +145,7 @@ public class SerializableImage implements Serializable {
private void writeObject(ObjectOutputStream out) throws IOException {
try {
ImageHelper.write(image, "png", out);
ImageHelper.write(image, ImageFormat.PNG, out);
} catch (Exception ex) {
// ignore
}