mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-02 20:04:37 +00:00
Fixed: #2308 FLA export - lossless image bin files generation wrong,
some javadoc added
This commit is contained in:
@@ -21,8 +21,6 @@ import com.jpexs.helpers.Helper;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -31,11 +29,18 @@ import java.util.zip.DeflaterOutputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
*
|
||||
* Generates bin/*.dat file for images.
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ImageBinDataGenerator {
|
||||
|
||||
/**
|
||||
* Generates data
|
||||
* @param is Input stream
|
||||
* @param os Output stream
|
||||
* @param format Image format
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public void generateBinData(InputStream is, OutputStream os, ImageFormat format) throws IOException {
|
||||
byte[] inputData = Helper.readStream(is);
|
||||
BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(inputData));
|
||||
@@ -58,9 +63,9 @@ public class ImageBinDataGenerator {
|
||||
w.writeUI16(bimg.getWidth());
|
||||
w.writeUI16(bimg.getHeight());
|
||||
|
||||
w.writeUI32(0);
|
||||
w.writeUI32(0);
|
||||
w.writeUI32(20 * bimg.getWidth());
|
||||
w.writeUI32(0);
|
||||
w.writeUI32(20 * bimg.getHeight());
|
||||
|
||||
w.write(0x01); //has transparency
|
||||
@@ -72,10 +77,27 @@ public class ImageBinDataGenerator {
|
||||
for (int y = 0; y < bimg.getHeight(); y++) {
|
||||
for (int x = 0; x < bimg.getWidth(); x++) {
|
||||
int rgba = bimg.getRGB(x, y);
|
||||
def.write((rgba >> 24) & 0xFF); //a
|
||||
def.write((rgba >> 16) & 0xFF); //b
|
||||
def.write((rgba >> 8) & 0xFF); //g
|
||||
def.write(rgba & 0xFF); //r
|
||||
int a = (rgba >> 24) & 0xFF;
|
||||
int b = (rgba >> 16) & 0xFF;
|
||||
int g = (rgba >> 8) & 0xFF;
|
||||
int r = rgba & 0xFF;
|
||||
|
||||
//some weird premultiplication
|
||||
if (a != 255) {
|
||||
r = (int)Math.floor(r * a / 256f);
|
||||
g = (int)Math.floor(g * a / 256f);
|
||||
b = (int)Math.floor(b * a / 256f);
|
||||
}
|
||||
|
||||
//also weird, but this way it works...
|
||||
if (a != 0 && a != 255) {
|
||||
a = a + 1;
|
||||
}
|
||||
|
||||
def.write(a);
|
||||
def.write(b);
|
||||
def.write(g);
|
||||
def.write(r);
|
||||
}
|
||||
}
|
||||
def.flush();
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2024 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.xfl;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
/**
|
||||
* Reads bin/*.dat file of lossless images and produces BufferedImage
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LosslessImageBinDataReader {
|
||||
|
||||
private final DataInputStream is;
|
||||
|
||||
public LosslessImageBinDataReader(InputStream is) {
|
||||
this.is = new DataInputStream(is);
|
||||
}
|
||||
|
||||
public BufferedImage readImage() throws IOException {
|
||||
int sign1 = readEx();
|
||||
int sign2 = readEx();
|
||||
if (sign1 != 0x03 || sign2 != 0x05) {
|
||||
throw new IOException("Invalid image");
|
||||
}
|
||||
int rowSize = readUI16();
|
||||
int width = readUI16();
|
||||
int height = readUI16();
|
||||
long frameLeft = readUI32();
|
||||
long frameRight = readUI32();
|
||||
long frameTop = readUI32();
|
||||
long frameBottom = readUI32();
|
||||
int flags = readEx();
|
||||
|
||||
boolean hasAlpha = (flags & 1) == 1;
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
int variant = readEx();
|
||||
if (variant == 1) { //compressed
|
||||
while (true) {
|
||||
int chunkLen = readUI16();
|
||||
if (chunkLen == 0) {
|
||||
break;
|
||||
}
|
||||
byte[] chunk = new byte[chunkLen];
|
||||
is.readFully(chunk);
|
||||
baos.write(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
byte[] buf = new byte[4096];
|
||||
int cnt;
|
||||
while ((cnt = iis.read(buf)) > 0) {
|
||||
baos2.write(buf, 0, cnt);
|
||||
}
|
||||
|
||||
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
byte[] data = baos2.toByteArray();
|
||||
int pos = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int a = data[pos++] & 0xFF;
|
||||
int b = data[pos++] & 0xFF;
|
||||
int g = data[pos++] & 0xFF;
|
||||
int r = data[pos++] & 0xFF;
|
||||
|
||||
if (a != 0 && a != 255) {
|
||||
a = a - 1;
|
||||
|
||||
r = (int)Math.floor(r * 256f / a);
|
||||
g = (int)Math.floor(g * 256f / a);
|
||||
b = (int)Math.floor(b * 256f / a);
|
||||
}
|
||||
|
||||
int rgba = r + (g << 8) + (b << 16) + (a << 24);
|
||||
img.setRGB(x, y, rgba);
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
private int readUI16() throws IOException {
|
||||
return readEx() + (readEx() << 8);
|
||||
}
|
||||
|
||||
private long readUI32() throws IOException {
|
||||
return (readEx() + (readEx() << 8) + (readEx() << 16) + (readEx() << 24)) & 0xffffffffL;
|
||||
}
|
||||
|
||||
private int readEx() throws IOException {
|
||||
int ret = is.read();
|
||||
if (ret == -1) {
|
||||
throw new IOException("Premature end of the file reached");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
File f = new File("in.bin");
|
||||
LosslessImageBinDataReader r = new LosslessImageBinDataReader(new FileInputStream(f));
|
||||
BufferedImage i = r.readImage();
|
||||
ImageIO.write(i, "PNG", new File("out.png"));
|
||||
}
|
||||
}
|
||||
@@ -33,11 +33,15 @@ import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* Generates bin/*.dat file for movies.
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MovieBinDataGenerator {
|
||||
|
||||
/**
|
||||
* Generates empty bin data.
|
||||
* @return Byte array
|
||||
*/
|
||||
public byte[] generateEmptyBinData() {
|
||||
return new byte[]{
|
||||
(byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
|
||||
@@ -56,6 +60,13 @@ public class MovieBinDataGenerator {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates data
|
||||
* @param is Input stream
|
||||
* @param os Output stream
|
||||
* @param fps SWF fps
|
||||
* @throws IOException On I/O error
|
||||
*/
|
||||
public void generateBinData(InputStream is, OutputStream os, float fps) throws IOException {
|
||||
BinDataOutputStream df = new BinDataOutputStream(os);
|
||||
FLVInputStream flvIs = new FLVInputStream(is);
|
||||
|
||||
Reference in New Issue
Block a user