mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-03 14:45:28 +00:00
Fixed #1974 DefineBits image reading problem
This commit is contained in:
committed by
Jindra Petřík
parent
bd6a0ea829
commit
c71bb08505
@@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.JpegFixer;
|
||||
import com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
@@ -116,73 +117,20 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener {
|
||||
public ImageFormat getOriginalImageFormat() {
|
||||
return ImageFormat.JPEG;
|
||||
}
|
||||
|
||||
private static List<byte[]> parseJpegChunks(byte[] data) {
|
||||
//A little inspired by shum way :-)
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
int pos = 0;
|
||||
int n = data.length;
|
||||
// Finding first marker, and skipping the data before this marker.
|
||||
// (FF 00 - code is escaped FF; FF FF ... (FF xx) - fill bytes before marker).
|
||||
while (pos < n && ((data[pos] & 0xFF) != 0xFF
|
||||
|| (pos + 1 < n && ((data[pos + 1] & 0xFF) == 0x00 || (data[pos + 1] & 0xFF) == 0xFF)))) {
|
||||
pos++;
|
||||
}
|
||||
|
||||
while (pos < n) {
|
||||
int start = pos++;
|
||||
int code = data[pos++] & 0xFF;
|
||||
|
||||
// Some tags have length field -- using it
|
||||
if ((code >= 0xC0 && code <= 0xC7)
|
||||
|| (code >= 0xC9 && code <= 0xCF)
|
||||
|| (code >= 0xDA && code <= 0xEF)
|
||||
|| code == 0xFE) {
|
||||
int length = (data[pos] & 0xFF) << 8 + (data[pos + 1] & 0xFF);
|
||||
pos += length;
|
||||
}
|
||||
|
||||
// Finding next marker.
|
||||
while (pos < n && ((data[pos] & 0xFF) != 0xFF
|
||||
|| (pos + 1 < n && ((data[pos + 1] & 0xff) == 0x00 || (data[pos + 1] & 0xFF) == 0xFF)))) {
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (code == 0xD8 || code == 0xD9) {
|
||||
// Removing SOI and EOI to avoid wrong EOI-SOI pairs in the middle.
|
||||
continue;
|
||||
}
|
||||
ret.add(Arrays.copyOfRange(data, start, pos));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public InputStream getOriginalImageData() {
|
||||
if (swf.getJtt() != null) {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
int errorLength = hasErrorHeader(jpegData) ? 4 : 0;
|
||||
|
||||
List<byte[]> jpegChunks = parseJpegChunks(jpegData.getRangeData(errorLength, jpegData.getLength() - errorLength));
|
||||
ByteArrayRange jttdata = swf.getJtt().jpegData;
|
||||
if (jttdata.getLength() != 0) {
|
||||
int jttErrorLength = hasErrorHeader(jttdata) ? 4 : 0;
|
||||
List<byte[]> chunksJtt = parseJpegChunks(jttdata.getRangeData(jttErrorLength, jttdata.getLength() - jttErrorLength));
|
||||
for (int c = 0; c < jpegChunks.size(); c++) {
|
||||
int chunkType = (jpegChunks.get(c)[1] & 0xFF);
|
||||
if (chunkType >= 0xC0 && chunkType <= 0xCF) {
|
||||
jpegChunks.addAll(c, chunksJtt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
baos.write(jttdata.getRangeData());
|
||||
}
|
||||
jpegChunks.add(0, new byte[]{(byte) 0xFF, (byte) 0xD8}); //SOI to beginning
|
||||
jpegChunks.add(new byte[]{(byte) 0xFF, (byte) 0xD9}); //EOI to the end
|
||||
|
||||
for (byte[] chunk : jpegChunks) {
|
||||
baos.write(chunk);
|
||||
}
|
||||
return new ByteArrayInputStream(baos.toByteArray());
|
||||
baos.write(jpegData.getRangeData());
|
||||
JpegFixer fixer = new JpegFixer();
|
||||
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
fixer.fixJpeg(new ByteArrayInputStream(baos.toByteArray()), baos2);
|
||||
return new ByteArrayInputStream(baos2.toByteArray());
|
||||
} catch (IOException ex) {
|
||||
// this should never happen, since IOException comes from OutputStream, but ByteArrayOutputStream should never throw it
|
||||
throw new Error(ex);
|
||||
|
||||
Reference in New Issue
Block a user