mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-15 06:22:08 +00:00
Saving files before refreshing line endings
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,105 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2016 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;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.conversion.IggySwfBundle;
|
||||
import com.jpexs.helpers.Path;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SWFSourceInfo {
|
||||
|
||||
private final InputStream inputStream;
|
||||
|
||||
private String file;
|
||||
|
||||
private final String fileTitle;
|
||||
|
||||
public SWFSourceInfo(InputStream inputStream, String file, String fileTitle) {
|
||||
this.inputStream = inputStream;
|
||||
this.file = file;
|
||||
this.fileTitle = fileTitle;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(String file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public String getFileTitle() {
|
||||
return fileTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title of the file
|
||||
*
|
||||
* @return file title
|
||||
*/
|
||||
public String getFileTitleOrName() {
|
||||
if (fileTitle != null) {
|
||||
return fileTitle;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public boolean isBundle() {
|
||||
if (inputStream == null) {
|
||||
File fileObj = new File(file);
|
||||
String fileName = fileObj.getName();
|
||||
if (fileName.startsWith("asdec_") && fileName.endsWith(".tmp")) {
|
||||
return false;
|
||||
}
|
||||
String extension = Path.getExtension(fileObj);
|
||||
return extension == null || !(extension.equals(".swf") || extension.equals(".gfx"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public SWFBundle getBundle(boolean noCheck, SearchMode searchMode) throws IOException {
|
||||
if (!isBundle()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String extension = Path.getExtension(new File(file));
|
||||
if (extension != null) {
|
||||
switch (extension) {
|
||||
case ".swc":
|
||||
return new SWC(new File(file));
|
||||
case ".zip":
|
||||
return new ZippedSWFBundle(new File(file));
|
||||
case ".iggy":
|
||||
return new IggySwfBundle(new File(file));
|
||||
}
|
||||
}
|
||||
|
||||
return new BinarySWFBundle(new BufferedInputStream(new FileInputStream(file)), noCheck, searchMode);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2010-2016 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;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.conversion.IggySwfBundle;
|
||||
import com.jpexs.helpers.Path;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SWFSourceInfo {
|
||||
|
||||
private final InputStream inputStream;
|
||||
|
||||
private String file;
|
||||
|
||||
private final String fileTitle;
|
||||
|
||||
public SWFSourceInfo(InputStream inputStream, String file, String fileTitle) {
|
||||
this.inputStream = inputStream;
|
||||
this.file = file;
|
||||
this.fileTitle = fileTitle;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(String file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public String getFileTitle() {
|
||||
return fileTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title of the file
|
||||
*
|
||||
* @return file title
|
||||
*/
|
||||
public String getFileTitleOrName() {
|
||||
if (fileTitle != null) {
|
||||
return fileTitle;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public boolean isBundle() {
|
||||
if (inputStream == null) {
|
||||
File fileObj = new File(file);
|
||||
String fileName = fileObj.getName();
|
||||
if (fileName.startsWith("asdec_") && fileName.endsWith(".tmp")) {
|
||||
return false;
|
||||
}
|
||||
String extension = Path.getExtension(fileObj);
|
||||
return extension == null || !(extension.equals(".swf") || extension.equals(".gfx"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public SWFBundle getBundle(boolean noCheck, SearchMode searchMode) throws IOException {
|
||||
if (!isBundle()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String extension = Path.getExtension(new File(file));
|
||||
if (extension != null) {
|
||||
switch (extension) {
|
||||
case ".swc":
|
||||
return new SWC(new File(file));
|
||||
case ".zip":
|
||||
return new ZippedSWFBundle(new File(file));
|
||||
case ".iggy":
|
||||
return new IggySwfBundle(new File(file));
|
||||
}
|
||||
}
|
||||
|
||||
return new BinarySWFBundle(new BufferedInputStream(new FileInputStream(file)), noCheck, searchMode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,110 +1,110 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class AbstractDataStream {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
public abstract Long available();
|
||||
|
||||
public abstract long position();
|
||||
|
||||
public abstract boolean is64();
|
||||
|
||||
protected long readUI64() throws IOException {
|
||||
try {
|
||||
return (readUI32() + (readUI32() << 32)) & 0xffffffffffffffffL;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI64(long val) throws IOException {
|
||||
write((int) (val & 0xff));
|
||||
write((int) ((val >> 8) & 0xff));
|
||||
write((int) ((val >> 16) & 0xff));
|
||||
write((int) ((val >> 24) & 0xff));
|
||||
|
||||
write((int) ((val >> 32) & 0xff));
|
||||
write((int) ((val >> 40) & 0xff));
|
||||
write((int) ((val >> 48) & 0xff));
|
||||
write((int) ((val >> 56) & 0xff));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected long readUI32() throws IOException {
|
||||
try {
|
||||
return (readUI8() + (readUI8() << 8) + (readUI8() << 16) + (readUI8() << 24));
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI32(long val) throws IOException {
|
||||
write((int) (val & 0xff));
|
||||
write((int) ((val >> 8) & 0xff));
|
||||
write((int) ((val >> 16) & 0xff));
|
||||
write((int) ((val >> 24) & 0xff));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int readUI16() throws IOException {
|
||||
try {
|
||||
return (readUI8() + (readUI8() << 8)) & 0xffff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI16(int val) throws IOException {
|
||||
write(val & 0xff);
|
||||
write((val >> 8) & 0xff);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int readUI8() throws IOException {
|
||||
try {
|
||||
return read() & 0xff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI8(int val) throws IOException {
|
||||
write(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat((int) readUI32());
|
||||
}
|
||||
|
||||
protected boolean writeFloat(float val) throws IOException {
|
||||
return writeUI32(Float.floatToIntBits(val));
|
||||
}
|
||||
|
||||
protected byte[] readBytes(int numBytes) throws IOException {
|
||||
byte[] ret = new byte[numBytes];
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected abstract int read() throws IOException;
|
||||
|
||||
protected abstract void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
protected void write(int val) throws IOException {
|
||||
//nothing
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class AbstractDataStream {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
public abstract Long available();
|
||||
|
||||
public abstract long position();
|
||||
|
||||
public abstract boolean is64();
|
||||
|
||||
protected long readUI64() throws IOException {
|
||||
try {
|
||||
return (readUI32() + (readUI32() << 32)) & 0xffffffffffffffffL;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI64(long val) throws IOException {
|
||||
write((int) (val & 0xff));
|
||||
write((int) ((val >> 8) & 0xff));
|
||||
write((int) ((val >> 16) & 0xff));
|
||||
write((int) ((val >> 24) & 0xff));
|
||||
|
||||
write((int) ((val >> 32) & 0xff));
|
||||
write((int) ((val >> 40) & 0xff));
|
||||
write((int) ((val >> 48) & 0xff));
|
||||
write((int) ((val >> 56) & 0xff));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected long readUI32() throws IOException {
|
||||
try {
|
||||
return (readUI8() + (readUI8() << 8) + (readUI8() << 16) + (readUI8() << 24));
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI32(long val) throws IOException {
|
||||
write((int) (val & 0xff));
|
||||
write((int) ((val >> 8) & 0xff));
|
||||
write((int) ((val >> 16) & 0xff));
|
||||
write((int) ((val >> 24) & 0xff));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int readUI16() throws IOException {
|
||||
try {
|
||||
return (readUI8() + (readUI8() << 8)) & 0xffff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI16(int val) throws IOException {
|
||||
write(val & 0xff);
|
||||
write((val >> 8) & 0xff);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int readUI8() throws IOException {
|
||||
try {
|
||||
return read() & 0xff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUI8(int val) throws IOException {
|
||||
write(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat((int) readUI32());
|
||||
}
|
||||
|
||||
protected boolean writeFloat(float val) throws IOException {
|
||||
return writeUI32(Float.floatToIntBits(val));
|
||||
}
|
||||
|
||||
protected byte[] readBytes(int numBytes) throws IOException {
|
||||
byte[] ret = new byte[numBytes];
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected abstract int read() throws IOException;
|
||||
|
||||
protected abstract void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
protected void write(int val) throws IOException {
|
||||
//nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,85 +1,85 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ByteArrayDataStream extends AbstractDataStream {
|
||||
|
||||
private byte[] data;
|
||||
private long pos;
|
||||
private boolean use64bit;
|
||||
|
||||
public ByteArrayDataStream(int initialSize, boolean use64bit) {
|
||||
this(new byte[initialSize], use64bit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long position() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public ByteArrayDataStream(byte data[], boolean use64bit) {
|
||||
this.data = data;
|
||||
pos = 0;
|
||||
this.use64bit = use64bit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is64() {
|
||||
return use64bit;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int read() throws IOException {
|
||||
if (pos >= data.length) {
|
||||
throw new EOFException("End of stream reached");
|
||||
}
|
||||
int ret = data[(int) pos] & 0xff;
|
||||
pos++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void resize(int newsize) {
|
||||
data = Arrays.copyOf(data, newsize);
|
||||
if (pos > data.length) {
|
||||
pos = data.length;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(int val) throws IOException {
|
||||
if (pos >= data.length) {
|
||||
throw new EOFException("End of stream reached");
|
||||
}
|
||||
data[(int) pos] = (byte) val;
|
||||
pos++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void seek(long pos, SeekMode mode) throws IOException {
|
||||
long newpos = pos;
|
||||
if (mode == SeekMode.CUR) {
|
||||
newpos = this.pos + pos;
|
||||
} else if (mode == SeekMode.END) {
|
||||
newpos = data.length - pos;
|
||||
}
|
||||
if (newpos > data.length) {
|
||||
throw new ArrayIndexOutOfBoundsException("Position outside bounds accessed: " + pos + ". Size: " + data.length);
|
||||
} else if (newpos < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("Negative position accessed: " + pos);
|
||||
} else {
|
||||
this.pos = (int) newpos;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long available() {
|
||||
return (long) (data.length - pos);
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ByteArrayDataStream extends AbstractDataStream {
|
||||
|
||||
private byte[] data;
|
||||
private long pos;
|
||||
private boolean use64bit;
|
||||
|
||||
public ByteArrayDataStream(int initialSize, boolean use64bit) {
|
||||
this(new byte[initialSize], use64bit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long position() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public ByteArrayDataStream(byte data[], boolean use64bit) {
|
||||
this.data = data;
|
||||
pos = 0;
|
||||
this.use64bit = use64bit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is64() {
|
||||
return use64bit;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int read() throws IOException {
|
||||
if (pos >= data.length) {
|
||||
throw new EOFException("End of stream reached");
|
||||
}
|
||||
int ret = data[(int) pos] & 0xff;
|
||||
pos++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void resize(int newsize) {
|
||||
data = Arrays.copyOf(data, newsize);
|
||||
if (pos > data.length) {
|
||||
pos = data.length;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(int val) throws IOException {
|
||||
if (pos >= data.length) {
|
||||
throw new EOFException("End of stream reached");
|
||||
}
|
||||
data[(int) pos] = (byte) val;
|
||||
pos++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void seek(long pos, SeekMode mode) throws IOException {
|
||||
long newpos = pos;
|
||||
if (mode == SeekMode.CUR) {
|
||||
newpos = this.pos + pos;
|
||||
} else if (mode == SeekMode.END) {
|
||||
newpos = data.length - pos;
|
||||
}
|
||||
if (newpos > data.length) {
|
||||
throw new ArrayIndexOutOfBoundsException("Position outside bounds accessed: " + pos + ". Size: " + data.length);
|
||||
} else if (newpos < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("Negative position accessed: " + pos);
|
||||
} else {
|
||||
this.pos = (int) newpos;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long available() {
|
||||
return (long) (data.length - pos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
/**
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum DataType {
|
||||
ubits, uint8_t, uint16_t, uint32_t, uint64_t, float_t, unknown,
|
||||
widechar_t //or maybe just "string"? It has two bytes per character and is null terminated
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
/**
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum DataType {
|
||||
ubits, uint8_t, uint16_t, uint32_t, uint64_t, float_t, unknown,
|
||||
widechar_t //or maybe just "string"? It has two bytes per character and is null terminated
|
||||
}
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharAdvances implements StructureInterface {
|
||||
|
||||
List<Float> advances;
|
||||
private long charCount;
|
||||
|
||||
public List<Float> getScales() {
|
||||
return advances;
|
||||
}
|
||||
|
||||
public IggyCharAdvances(AbstractDataStream stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
advances = new ArrayList<>();
|
||||
for (int i = 0; i < charCount; i++) {
|
||||
advances.add(stream.readFloat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharAdvances implements StructureInterface {
|
||||
|
||||
List<Float> advances;
|
||||
private long charCount;
|
||||
|
||||
public List<Float> getScales() {
|
||||
return advances;
|
||||
}
|
||||
|
||||
public IggyCharAdvances(AbstractDataStream stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
advances = new ArrayList<>();
|
||||
for (int i = 0; i < charCount; i++) {
|
||||
advances.add(stream.readFloat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharIndices implements StructureInterface {
|
||||
|
||||
@IggyFieldType(value = DataType.widechar_t)
|
||||
List<Character> chars;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long padd;
|
||||
|
||||
public List<Character> getChars() {
|
||||
return chars;
|
||||
}
|
||||
|
||||
private long charCount;
|
||||
|
||||
public IggyCharIndices(AbstractDataStream stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
chars = new ArrayList<>();
|
||||
for (int i = 0; i < charCount; i++) {
|
||||
chars.add((char) stream.readUI16());
|
||||
}
|
||||
padd = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharIndices implements StructureInterface {
|
||||
|
||||
@IggyFieldType(value = DataType.widechar_t)
|
||||
List<Character> chars;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long padd;
|
||||
|
||||
public List<Character> getChars() {
|
||||
return chars;
|
||||
}
|
||||
|
||||
private long charCount;
|
||||
|
||||
public IggyCharIndices(AbstractDataStream stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
chars = new ArrayList<>();
|
||||
for (int i = 0; i < charCount; i++) {
|
||||
chars.add((char) stream.readUI16());
|
||||
}
|
||||
padd = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharKerning implements StructureInterface {
|
||||
|
||||
private long kernCount;
|
||||
List<Character> charsA;
|
||||
List<Character> charsB;
|
||||
List<Short> kerningOffsets;
|
||||
long pad;
|
||||
|
||||
public long getKernCount() {
|
||||
return kernCount;
|
||||
}
|
||||
|
||||
public List<Character> getCharsA() {
|
||||
return charsA;
|
||||
}
|
||||
|
||||
public List<Character> getCharsB() {
|
||||
return charsB;
|
||||
}
|
||||
|
||||
public List<Short> getKerningOffsets() {
|
||||
return kerningOffsets;
|
||||
}
|
||||
|
||||
public IggyCharKerning(AbstractDataStream stream, long kernCount) throws IOException {
|
||||
this.kernCount = kernCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
charsA = new ArrayList<>();
|
||||
charsB = new ArrayList<>();
|
||||
kerningOffsets = new ArrayList<>();
|
||||
for (int i = 0; i < kernCount; i++) {
|
||||
charsA.add((char) stream.readUI16());
|
||||
charsB.add((char) stream.readUI16());
|
||||
kerningOffsets.add((short) stream.readUI16());
|
||||
}
|
||||
pad = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharKerning implements StructureInterface {
|
||||
|
||||
private long kernCount;
|
||||
List<Character> charsA;
|
||||
List<Character> charsB;
|
||||
List<Short> kerningOffsets;
|
||||
long pad;
|
||||
|
||||
public long getKernCount() {
|
||||
return kernCount;
|
||||
}
|
||||
|
||||
public List<Character> getCharsA() {
|
||||
return charsA;
|
||||
}
|
||||
|
||||
public List<Character> getCharsB() {
|
||||
return charsB;
|
||||
}
|
||||
|
||||
public List<Short> getKerningOffsets() {
|
||||
return kerningOffsets;
|
||||
}
|
||||
|
||||
public IggyCharKerning(AbstractDataStream stream, long kernCount) throws IOException {
|
||||
this.kernCount = kernCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
charsA = new ArrayList<>();
|
||||
charsB = new ArrayList<>();
|
||||
kerningOffsets = new ArrayList<>();
|
||||
for (int i = 0; i < kernCount; i++) {
|
||||
charsA.add((char) stream.readUI16());
|
||||
charsB.add((char) stream.readUI16());
|
||||
kerningOffsets.add((short) stream.readUI16());
|
||||
}
|
||||
pad = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,99 +1,99 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharOffset implements StructureInterface {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyCharOffset.class.getName());
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int ischar1;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int ischar2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero2;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int xscale;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int yscale;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero3;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long offset;
|
||||
|
||||
public IggyCharOffset(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyCharOffset(long zero, int ischar1, int ischar2, long zero2, int xscale, int yscale, long zero3, long offset) {
|
||||
this.zero = zero;
|
||||
this.ischar1 = ischar1;
|
||||
this.ischar2 = ischar2;
|
||||
this.zero2 = zero2;
|
||||
this.xscale = xscale;
|
||||
this.yscale = yscale;
|
||||
this.zero3 = zero3;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
zero = stream.readUI64();
|
||||
ischar1 = stream.readUI16();
|
||||
ischar2 = stream.readUI16();
|
||||
zero2 = stream.readUI32();
|
||||
xscale = stream.readUI16();
|
||||
yscale = stream.readUI16();
|
||||
zero3 = stream.readUI32();
|
||||
long cur_position = stream.position();
|
||||
long relative_offset = stream.readUI64();
|
||||
if (ischar1 > 0) {
|
||||
offset = cur_position + relative_offset;
|
||||
} else {
|
||||
offset = 0;
|
||||
LOGGER.finer(String.format("Empty char"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public long getZero() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
public boolean isChar1() {
|
||||
return ischar1 > 0;
|
||||
}
|
||||
|
||||
public boolean isChar2() {
|
||||
return ischar2 > 0;
|
||||
}
|
||||
|
||||
public long getZero2() {
|
||||
return zero2;
|
||||
}
|
||||
|
||||
public int getXscale() {
|
||||
return xscale;
|
||||
}
|
||||
|
||||
public int getYscale() {
|
||||
return yscale;
|
||||
}
|
||||
|
||||
public long getZero3() {
|
||||
return zero3;
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharOffset implements StructureInterface {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyCharOffset.class.getName());
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int ischar1;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int ischar2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero2;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int xscale;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int yscale;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero3;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long offset;
|
||||
|
||||
public IggyCharOffset(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyCharOffset(long zero, int ischar1, int ischar2, long zero2, int xscale, int yscale, long zero3, long offset) {
|
||||
this.zero = zero;
|
||||
this.ischar1 = ischar1;
|
||||
this.ischar2 = ischar2;
|
||||
this.zero2 = zero2;
|
||||
this.xscale = xscale;
|
||||
this.yscale = yscale;
|
||||
this.zero3 = zero3;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
zero = stream.readUI64();
|
||||
ischar1 = stream.readUI16();
|
||||
ischar2 = stream.readUI16();
|
||||
zero2 = stream.readUI32();
|
||||
xscale = stream.readUI16();
|
||||
yscale = stream.readUI16();
|
||||
zero3 = stream.readUI32();
|
||||
long cur_position = stream.position();
|
||||
long relative_offset = stream.readUI64();
|
||||
if (ischar1 > 0) {
|
||||
offset = cur_position + relative_offset;
|
||||
} else {
|
||||
offset = 0;
|
||||
LOGGER.finer(String.format("Empty char"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public long getZero() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
public boolean isChar1() {
|
||||
return ischar1 > 0;
|
||||
}
|
||||
|
||||
public boolean isChar2() {
|
||||
return ischar2 > 0;
|
||||
}
|
||||
|
||||
public long getZero2() {
|
||||
return zero2;
|
||||
}
|
||||
|
||||
public int getXscale() {
|
||||
return xscale;
|
||||
}
|
||||
|
||||
public int getYscale() {
|
||||
return yscale;
|
||||
}
|
||||
|
||||
public long getZero3() {
|
||||
return zero3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,89 +1,89 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyDataReader implements StructureInterface {
|
||||
|
||||
final static int NO_OFFSET = 1;
|
||||
|
||||
@IggyFieldType(value = DataType.widechar_t, count = 48)
|
||||
String name;
|
||||
|
||||
Map<Integer, IggyFont> fonts;
|
||||
Map<Integer, IggyText> texts;
|
||||
Map<Integer, Integer> text2Font;
|
||||
|
||||
private IggyFlashHeader64 header;
|
||||
private Map<Long, Long> sizesOfOffsets;
|
||||
private List<Long> allOffsets;
|
||||
|
||||
public IggyDataReader(IggyFlashHeader64 header, AbstractDataStream stream, List<Long> offsets) throws IOException {
|
||||
this.header = header;
|
||||
sizesOfOffsets = new HashMap<>();
|
||||
for (int i = 0; i < offsets.size() - 1; i++) {
|
||||
sizesOfOffsets.put(offsets.get(i), offsets.get(i + 1) - offsets.get(i));
|
||||
}
|
||||
sizesOfOffsets.put(offsets.get(offsets.size() - 1), 0L); //Last offset has 0L length?
|
||||
this.allOffsets = offsets;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
//here is offset[0]
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
do {
|
||||
char c = (char) stream.readUI16();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
nameBuilder.append(c);
|
||||
} while (true);
|
||||
name = nameBuilder.toString();
|
||||
//here is offset[1]
|
||||
int pad8 = 8 - (int) (stream.position() % 8);
|
||||
stream.seek(pad8, SeekMode.CUR);
|
||||
//here is offset [2]
|
||||
fonts = new HashMap<>();
|
||||
int fontIndex = 0;
|
||||
for (int i = 2; i < allOffsets.size(); i++) {
|
||||
long offset = allOffsets.get(i);
|
||||
stream.seek(offset, SeekMode.SET);
|
||||
int type = stream.readUI16();
|
||||
stream.seek(-2, SeekMode.CUR);
|
||||
if (type == IggyFont.ID) {
|
||||
IggyFont font = new IggyFont(stream);
|
||||
fonts.put(fontIndex++, font);
|
||||
}
|
||||
if (type == IggyText.ID) {
|
||||
//TODO: Texts - incomplete
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[\r\n");
|
||||
sb.append("name ").append(name).append("\r\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyDataReader implements StructureInterface {
|
||||
|
||||
final static int NO_OFFSET = 1;
|
||||
|
||||
@IggyFieldType(value = DataType.widechar_t, count = 48)
|
||||
String name;
|
||||
|
||||
Map<Integer, IggyFont> fonts;
|
||||
Map<Integer, IggyText> texts;
|
||||
Map<Integer, Integer> text2Font;
|
||||
|
||||
private IggyFlashHeader64 header;
|
||||
private Map<Long, Long> sizesOfOffsets;
|
||||
private List<Long> allOffsets;
|
||||
|
||||
public IggyDataReader(IggyFlashHeader64 header, AbstractDataStream stream, List<Long> offsets) throws IOException {
|
||||
this.header = header;
|
||||
sizesOfOffsets = new HashMap<>();
|
||||
for (int i = 0; i < offsets.size() - 1; i++) {
|
||||
sizesOfOffsets.put(offsets.get(i), offsets.get(i + 1) - offsets.get(i));
|
||||
}
|
||||
sizesOfOffsets.put(offsets.get(offsets.size() - 1), 0L); //Last offset has 0L length?
|
||||
this.allOffsets = offsets;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
//here is offset[0]
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
do {
|
||||
char c = (char) stream.readUI16();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
nameBuilder.append(c);
|
||||
} while (true);
|
||||
name = nameBuilder.toString();
|
||||
//here is offset[1]
|
||||
int pad8 = 8 - (int) (stream.position() % 8);
|
||||
stream.seek(pad8, SeekMode.CUR);
|
||||
//here is offset [2]
|
||||
fonts = new HashMap<>();
|
||||
int fontIndex = 0;
|
||||
for (int i = 2; i < allOffsets.size(); i++) {
|
||||
long offset = allOffsets.get(i);
|
||||
stream.seek(offset, SeekMode.SET);
|
||||
int type = stream.readUI16();
|
||||
stream.seek(-2, SeekMode.CUR);
|
||||
if (type == IggyFont.ID) {
|
||||
IggyFont font = new IggyFont(stream);
|
||||
fonts.put(fontIndex++, font);
|
||||
}
|
||||
if (type == IggyText.ID) {
|
||||
//TODO: Texts - incomplete
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[\r\n");
|
||||
sb.append("name ").append(name).append("\r\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,195 +1,195 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*
|
||||
* All relative offsets are relative from that specific field position All
|
||||
* relative offsets can get value "1" to indicate "nothing"
|
||||
*/
|
||||
public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long main_offset; // 0 Relative offset to first section (matches sizeof header)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long as3_section_offset; // 4 Relative offset to as3 file names table...
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset; // 8 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset2; // 0xC relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset3; // 0x10 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset4; // 0x14 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmin; //0x18 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymin; //0x0C in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmax; // 0x20 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymax; // 0x24 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_28; // probably number of blocks/objects after header
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_2C;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_30;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_34;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_38;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_3C;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float frameRate;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_44;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_48;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_4C;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long names_offset; // 0x50 relative offset to the names/import section of the file
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset5; // 0x54 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_58; // Maybe number of imports/names pointed by names_offset
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long last_section_offset; // 0x60 relative offset, points to the small last section of the file
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset6; // 0x64 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long as3_code_offset; // 0x68 relative offset to as3 code (8 bytes header + abc blob)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long as3_names_offset; // 0x6C relative offset to as3 file names table (or classes names or whatever)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_70;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_74;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_78; // Maybe number of classes / as3 names
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_7C;
|
||||
|
||||
// Offset 0x80 (outside header): there are *unk_28* relative offsets that point to flash objects.
|
||||
// The flash objects are in a format different to swf but there is probably a way to convert between them.
|
||||
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
|
||||
// for the object.
|
||||
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
|
||||
// it is written in a different way.
|
||||
public IggyFlashHeader32(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
main_offset = stream.readUI32();
|
||||
as3_section_offset = stream.readUI32();
|
||||
unk_offset = stream.readUI32();
|
||||
unk_offset2 = stream.readUI32();
|
||||
unk_offset3 = stream.readUI32();
|
||||
unk_offset4 = stream.readUI32();
|
||||
xmin = stream.readUI32();
|
||||
ymin = stream.readUI32();
|
||||
xmax = stream.readUI32();
|
||||
ymax = stream.readUI32();
|
||||
unk_28 = stream.readUI32();
|
||||
unk_2C = stream.readUI32();
|
||||
unk_30 = stream.readUI32();
|
||||
unk_34 = stream.readUI32();
|
||||
unk_38 = stream.readUI32();
|
||||
unk_3C = stream.readUI32();
|
||||
frameRate = stream.readFloat();
|
||||
unk_44 = stream.readUI32();
|
||||
unk_48 = stream.readUI32();
|
||||
unk_4C = stream.readUI32();
|
||||
unk_3C = stream.readUI32();
|
||||
names_offset = stream.readUI32();
|
||||
unk_offset5 = stream.readUI32();
|
||||
unk_58 = stream.readUI64();
|
||||
last_section_offset = stream.readUI32();
|
||||
unk_offset6 = stream.readUI32();
|
||||
as3_code_offset = stream.readUI32();
|
||||
as3_names_offset = stream.readUI32();
|
||||
unk_70 = stream.readUI32();
|
||||
unk_74 = stream.readUI32();
|
||||
unk_78 = stream.readUI32();
|
||||
unk_7C = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("[\r\n");
|
||||
sb.append("main_offset ").append(main_offset).append("\r\n");
|
||||
sb.append("as3_section_offset ").append(as3_section_offset).append("\r\n");
|
||||
sb.append("unk_offset ").append(unk_offset).append("\r\n");
|
||||
sb.append("unk_offset2 ").append(unk_offset2).append("\r\n");
|
||||
sb.append("unk_offset3 ").append(unk_offset3).append("\r\n");
|
||||
sb.append("unk_offset4 ").append(unk_offset4).append("\r\n");
|
||||
sb.append("xmin ").append(xmin).append("\r\n");
|
||||
sb.append("ymin ").append(ymin).append("\r\n");
|
||||
sb.append("xmax ").append(xmax).append("\r\n");
|
||||
sb.append("ymax ").append(ymax).append("\r\n");
|
||||
sb.append("unk_28 ").append(unk_28).append("\r\n");
|
||||
sb.append("unk_2C ").append(unk_2C).append("\r\n");
|
||||
sb.append("unk_30 ").append(unk_30).append("\r\n");
|
||||
sb.append("unk_34 ").append(unk_34).append("\r\n");
|
||||
sb.append("unk_38 ").append(unk_38).append("\r\n");
|
||||
sb.append("unk_3C ").append(unk_3C).append("\r\n");
|
||||
sb.append("frameRate ").append(frameRate).append("\r\n");
|
||||
sb.append("unk_44 ").append(unk_44).append("\r\n");
|
||||
sb.append("unk_48 ").append(unk_48).append("\r\n");
|
||||
sb.append("unk_4C ").append(unk_4C).append("\r\n");
|
||||
sb.append("names_offset ").append(names_offset).append("\r\n");
|
||||
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
|
||||
sb.append("unk_58 ").append(unk_58).append("\r\n");
|
||||
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
|
||||
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
|
||||
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
|
||||
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
|
||||
sb.append("unk_70 ").append(unk_70).append("\r\n");
|
||||
sb.append("unk_74 ").append(unk_74).append("\r\n");
|
||||
sb.append("unk_78 ").append(unk_78).append("\r\n");
|
||||
sb.append("unk_7C ").append(unk_7C).append("\r\n");
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frameRate;
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*
|
||||
* All relative offsets are relative from that specific field position All
|
||||
* relative offsets can get value "1" to indicate "nothing"
|
||||
*/
|
||||
public class IggyFlashHeader32 implements IggyFlashHeaderInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long main_offset; // 0 Relative offset to first section (matches sizeof header)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long as3_section_offset; // 4 Relative offset to as3 file names table...
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset; // 8 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset2; // 0xC relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset3; // 0x10 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset4; // 0x14 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmin; //0x18 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymin; //0x0C in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmax; // 0x20 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymax; // 0x24 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_28; // probably number of blocks/objects after header
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_2C;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_30;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_34;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_38;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_3C;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float frameRate;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_44;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_48;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_4C;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long names_offset; // 0x50 relative offset to the names/import section of the file
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset5; // 0x54 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_58; // Maybe number of imports/names pointed by names_offset
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long last_section_offset; // 0x60 relative offset, points to the small last section of the file
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_offset6; // 0x64 relative offset to something
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long as3_code_offset; // 0x68 relative offset to as3 code (8 bytes header + abc blob)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long as3_names_offset; // 0x6C relative offset to as3 file names table (or classes names or whatever)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_70;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_74;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_78; // Maybe number of classes / as3 names
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_7C;
|
||||
|
||||
// Offset 0x80 (outside header): there are *unk_28* relative offsets that point to flash objects.
|
||||
// The flash objects are in a format different to swf but there is probably a way to convert between them.
|
||||
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
|
||||
// for the object.
|
||||
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
|
||||
// it is written in a different way.
|
||||
public IggyFlashHeader32(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
main_offset = stream.readUI32();
|
||||
as3_section_offset = stream.readUI32();
|
||||
unk_offset = stream.readUI32();
|
||||
unk_offset2 = stream.readUI32();
|
||||
unk_offset3 = stream.readUI32();
|
||||
unk_offset4 = stream.readUI32();
|
||||
xmin = stream.readUI32();
|
||||
ymin = stream.readUI32();
|
||||
xmax = stream.readUI32();
|
||||
ymax = stream.readUI32();
|
||||
unk_28 = stream.readUI32();
|
||||
unk_2C = stream.readUI32();
|
||||
unk_30 = stream.readUI32();
|
||||
unk_34 = stream.readUI32();
|
||||
unk_38 = stream.readUI32();
|
||||
unk_3C = stream.readUI32();
|
||||
frameRate = stream.readFloat();
|
||||
unk_44 = stream.readUI32();
|
||||
unk_48 = stream.readUI32();
|
||||
unk_4C = stream.readUI32();
|
||||
unk_3C = stream.readUI32();
|
||||
names_offset = stream.readUI32();
|
||||
unk_offset5 = stream.readUI32();
|
||||
unk_58 = stream.readUI64();
|
||||
last_section_offset = stream.readUI32();
|
||||
unk_offset6 = stream.readUI32();
|
||||
as3_code_offset = stream.readUI32();
|
||||
as3_names_offset = stream.readUI32();
|
||||
unk_70 = stream.readUI32();
|
||||
unk_74 = stream.readUI32();
|
||||
unk_78 = stream.readUI32();
|
||||
unk_7C = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("[\r\n");
|
||||
sb.append("main_offset ").append(main_offset).append("\r\n");
|
||||
sb.append("as3_section_offset ").append(as3_section_offset).append("\r\n");
|
||||
sb.append("unk_offset ").append(unk_offset).append("\r\n");
|
||||
sb.append("unk_offset2 ").append(unk_offset2).append("\r\n");
|
||||
sb.append("unk_offset3 ").append(unk_offset3).append("\r\n");
|
||||
sb.append("unk_offset4 ").append(unk_offset4).append("\r\n");
|
||||
sb.append("xmin ").append(xmin).append("\r\n");
|
||||
sb.append("ymin ").append(ymin).append("\r\n");
|
||||
sb.append("xmax ").append(xmax).append("\r\n");
|
||||
sb.append("ymax ").append(ymax).append("\r\n");
|
||||
sb.append("unk_28 ").append(unk_28).append("\r\n");
|
||||
sb.append("unk_2C ").append(unk_2C).append("\r\n");
|
||||
sb.append("unk_30 ").append(unk_30).append("\r\n");
|
||||
sb.append("unk_34 ").append(unk_34).append("\r\n");
|
||||
sb.append("unk_38 ").append(unk_38).append("\r\n");
|
||||
sb.append("unk_3C ").append(unk_3C).append("\r\n");
|
||||
sb.append("frameRate ").append(frameRate).append("\r\n");
|
||||
sb.append("unk_44 ").append(unk_44).append("\r\n");
|
||||
sb.append("unk_48 ").append(unk_48).append("\r\n");
|
||||
sb.append("unk_4C ").append(unk_4C).append("\r\n");
|
||||
sb.append("names_offset ").append(names_offset).append("\r\n");
|
||||
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
|
||||
sb.append("unk_58 ").append(unk_58).append("\r\n");
|
||||
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
|
||||
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
|
||||
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
|
||||
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
|
||||
sb.append("unk_70 ").append(unk_70).append("\r\n");
|
||||
sb.append("unk_74 ").append(unk_74).append("\r\n");
|
||||
sb.append("unk_78 ").append(unk_78).append("\r\n");
|
||||
sb.append("unk_7C ").append(unk_7C).append("\r\n");
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frameRate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,211 +1,211 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long main_offset; // 0 Relative offset to first section (matches sizeof header);
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long as3_section_offset; // 8 Relative offset to as3 file names table...
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset; // 0x10 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset2; // 0x18 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset3; // 0x20 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset4; // 0x28 names_offset; 0x50 relative pointer to the names/import section of the file
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmin; // 0x30 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymin; // 0x34 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmax; // 0x38 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymax; // 0x3C in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_40; // probably numer of blocks/objects after header
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_44;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_48;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_4C;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_50;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_54;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float frame_rate;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_5C;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long fonts_offset;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_68;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long names_offset; // 0x70 relative offset to the names/import section of the file - end of fonts
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset5; // 0x78 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_80; // Maybe number of imports/names pointed by names_offset
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long last_section_offset; // 0x88 relative offset, points to the small last section of the file
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset6; // 0x90 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long as3_code_offset; // 0x98 relative offset to as3 code (16 bytes header + abc blob)
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long as3_names_offset; // 0xA0 relative offset to as3 file names table (or classes names or whatever)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_A8;
|
||||
@IggyFieldType(DataType.uint32_t) //font_main_off
|
||||
long unk_AC; //font_main_size
|
||||
@IggyFieldType(DataType.uint32_t) //font_info_off
|
||||
long font_count; // Maybe number of classes / as3 names //font_info_size
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_B4; //zero (?)
|
||||
|
||||
// Offset 0xB8 (outside header): there are *unk_40* relative offsets that point to flash objects.
|
||||
// The flash objects are in a format different to swf but there is probably a way to convert between them.
|
||||
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
|
||||
// for the object.
|
||||
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
|
||||
// it is written in a different way.
|
||||
public IggyFlashHeader64(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
main_offset = stream.readUI64();
|
||||
as3_section_offset = stream.readUI64();
|
||||
unk_offset = stream.readUI64();
|
||||
unk_offset2 = stream.readUI64();
|
||||
unk_offset3 = stream.readUI64();
|
||||
unk_offset4 = stream.readUI64();
|
||||
xmin = stream.readUI32();
|
||||
ymin = stream.readUI32();
|
||||
xmax = stream.readUI32();
|
||||
ymax = stream.readUI32();
|
||||
unk_40 = stream.readUI32();
|
||||
unk_44 = stream.readUI32();
|
||||
unk_48 = stream.readUI32();
|
||||
unk_4C = stream.readUI32();
|
||||
unk_50 = stream.readUI32();
|
||||
unk_54 = stream.readUI32();
|
||||
frame_rate = stream.readFloat();
|
||||
unk_5C = stream.readUI32();
|
||||
fonts_offset = stream.readUI64();
|
||||
unk_68 = stream.readUI64();
|
||||
names_offset = stream.readUI64();
|
||||
unk_offset5 = stream.readUI64();
|
||||
unk_80 = stream.readUI64();
|
||||
last_section_offset = stream.readUI64();
|
||||
unk_offset6 = stream.readUI64();
|
||||
as3_code_offset = stream.readUI64();
|
||||
as3_names_offset = stream.readUI64();
|
||||
unk_A8 = stream.readUI32();
|
||||
unk_AC = stream.readUI32();
|
||||
font_count = stream.readUI32();
|
||||
unk_B4 = stream.readUI32();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[\r\n");
|
||||
sb.append("main_offset ").append(main_offset).append("\r\n");
|
||||
sb.append("as3_section_offset ").append(as3_section_offset);
|
||||
sb.append(" global: ").append(main_offset + as3_section_offset);
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset ").append(unk_offset);
|
||||
if (unk_offset != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset2 ").append(unk_offset2);
|
||||
if (unk_offset2 != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset2);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset3 ").append(unk_offset3);
|
||||
if (unk_offset3 != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset3);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset4 ").append(unk_offset4);
|
||||
if (unk_offset4 != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset4);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("xmin ").append(xmin).append("\r\n");
|
||||
sb.append("ymin ").append(ymin).append("\r\n");
|
||||
sb.append("xmax ").append(ymax).append("\r\n");
|
||||
sb.append("ymax ").append(ymax).append("\r\n");
|
||||
sb.append("unk_40 ").append(unk_40).append("\r\n");
|
||||
sb.append("unk_44 ").append(unk_44).append("\r\n");
|
||||
sb.append("unk_48 ").append(unk_48).append("\r\n");
|
||||
sb.append("unk_4C ").append(unk_4C).append("\r\n");
|
||||
sb.append("unk_50 ").append(unk_50).append("\r\n");
|
||||
sb.append("unk_54 ").append(unk_54).append("\r\n");
|
||||
sb.append("frame_rate ").append(frame_rate).append("\r\n");
|
||||
sb.append("unk_5C ").append(unk_5C).append("\r\n");
|
||||
sb.append("fonts_offset ").append(fonts_offset).append("\r\n");
|
||||
sb.append("unk_68 ").append(unk_68).append("\r\n");
|
||||
sb.append("names_offset ").append(names_offset).append("\r\n");
|
||||
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
|
||||
sb.append("unk_80 ").append(unk_80).append("\r\n");
|
||||
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
|
||||
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
|
||||
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
|
||||
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
|
||||
sb.append("unk_A8 ").append(unk_A8).append("\r\n");
|
||||
sb.append("unk_AC ").append(unk_AC).append("\r\n");
|
||||
sb.append("font_count ").append(font_count).append("\r\n");
|
||||
sb.append("unk_B4 ").append(unk_B4).append("\r\n");
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frame_rate;
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long main_offset; // 0 Relative offset to first section (matches sizeof header);
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long as3_section_offset; // 8 Relative offset to as3 file names table...
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset; // 0x10 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset2; // 0x18 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset3; // 0x20 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset4; // 0x28 names_offset; 0x50 relative pointer to the names/import section of the file
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmin; // 0x30 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymin; // 0x34 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long xmax; // 0x38 in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long ymax; // 0x3C in pixels
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_40; // probably numer of blocks/objects after header
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_44;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_48;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_4C;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_50;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_54;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float frame_rate;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_5C;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long fonts_offset;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_68;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long names_offset; // 0x70 relative offset to the names/import section of the file - end of fonts
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset5; // 0x78 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_80; // Maybe number of imports/names pointed by names_offset
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long last_section_offset; // 0x88 relative offset, points to the small last section of the file
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk_offset6; // 0x90 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long as3_code_offset; // 0x98 relative offset to as3 code (16 bytes header + abc blob)
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long as3_names_offset; // 0xA0 relative offset to as3 file names table (or classes names or whatever)
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_A8;
|
||||
@IggyFieldType(DataType.uint32_t) //font_main_off
|
||||
long unk_AC; //font_main_size
|
||||
@IggyFieldType(DataType.uint32_t) //font_info_off
|
||||
long font_count; // Maybe number of classes / as3 names //font_info_size
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long unk_B4; //zero (?)
|
||||
|
||||
// Offset 0xB8 (outside header): there are *unk_40* relative offsets that point to flash objects.
|
||||
// The flash objects are in a format different to swf but there is probably a way to convert between them.
|
||||
// After the offsets, the bodies of objects pointed above, which apparently have a code like 0xFFXX to identify the type of object, followed by a (unique?) identifier
|
||||
// for the object.
|
||||
// A DefineEditText-like object can be easily spotted and apparently uses type code 0x06 (or 0xFF06) but as stated above,
|
||||
// it is written in a different way.
|
||||
public IggyFlashHeader64(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
main_offset = stream.readUI64();
|
||||
as3_section_offset = stream.readUI64();
|
||||
unk_offset = stream.readUI64();
|
||||
unk_offset2 = stream.readUI64();
|
||||
unk_offset3 = stream.readUI64();
|
||||
unk_offset4 = stream.readUI64();
|
||||
xmin = stream.readUI32();
|
||||
ymin = stream.readUI32();
|
||||
xmax = stream.readUI32();
|
||||
ymax = stream.readUI32();
|
||||
unk_40 = stream.readUI32();
|
||||
unk_44 = stream.readUI32();
|
||||
unk_48 = stream.readUI32();
|
||||
unk_4C = stream.readUI32();
|
||||
unk_50 = stream.readUI32();
|
||||
unk_54 = stream.readUI32();
|
||||
frame_rate = stream.readFloat();
|
||||
unk_5C = stream.readUI32();
|
||||
fonts_offset = stream.readUI64();
|
||||
unk_68 = stream.readUI64();
|
||||
names_offset = stream.readUI64();
|
||||
unk_offset5 = stream.readUI64();
|
||||
unk_80 = stream.readUI64();
|
||||
last_section_offset = stream.readUI64();
|
||||
unk_offset6 = stream.readUI64();
|
||||
as3_code_offset = stream.readUI64();
|
||||
as3_names_offset = stream.readUI64();
|
||||
unk_A8 = stream.readUI32();
|
||||
unk_AC = stream.readUI32();
|
||||
font_count = stream.readUI32();
|
||||
unk_B4 = stream.readUI32();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[\r\n");
|
||||
sb.append("main_offset ").append(main_offset).append("\r\n");
|
||||
sb.append("as3_section_offset ").append(as3_section_offset);
|
||||
sb.append(" global: ").append(main_offset + as3_section_offset);
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset ").append(unk_offset);
|
||||
if (unk_offset != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset2 ").append(unk_offset2);
|
||||
if (unk_offset2 != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset2);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset3 ").append(unk_offset3);
|
||||
if (unk_offset3 != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset3);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("unk_offset4 ").append(unk_offset4);
|
||||
if (unk_offset4 != 1) {
|
||||
sb.append(" global: ").append(main_offset + unk_offset4);
|
||||
}
|
||||
sb.append("\r\n");
|
||||
sb.append("xmin ").append(xmin).append("\r\n");
|
||||
sb.append("ymin ").append(ymin).append("\r\n");
|
||||
sb.append("xmax ").append(ymax).append("\r\n");
|
||||
sb.append("ymax ").append(ymax).append("\r\n");
|
||||
sb.append("unk_40 ").append(unk_40).append("\r\n");
|
||||
sb.append("unk_44 ").append(unk_44).append("\r\n");
|
||||
sb.append("unk_48 ").append(unk_48).append("\r\n");
|
||||
sb.append("unk_4C ").append(unk_4C).append("\r\n");
|
||||
sb.append("unk_50 ").append(unk_50).append("\r\n");
|
||||
sb.append("unk_54 ").append(unk_54).append("\r\n");
|
||||
sb.append("frame_rate ").append(frame_rate).append("\r\n");
|
||||
sb.append("unk_5C ").append(unk_5C).append("\r\n");
|
||||
sb.append("fonts_offset ").append(fonts_offset).append("\r\n");
|
||||
sb.append("unk_68 ").append(unk_68).append("\r\n");
|
||||
sb.append("names_offset ").append(names_offset).append("\r\n");
|
||||
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
|
||||
sb.append("unk_80 ").append(unk_80).append("\r\n");
|
||||
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
|
||||
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
|
||||
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
|
||||
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
|
||||
sb.append("unk_A8 ").append(unk_A8).append("\r\n");
|
||||
sb.append("unk_AC ").append(unk_AC).append("\r\n");
|
||||
sb.append("font_count ").append(font_count).append("\r\n");
|
||||
sb.append("unk_B4 ").append(unk_B4).append("\r\n");
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frame_rate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface IggyFlashHeaderInterface extends StructureInterface {
|
||||
|
||||
public long getXMin();
|
||||
|
||||
public long getYMin();
|
||||
|
||||
public long getXMax();
|
||||
|
||||
public long getYMax();
|
||||
|
||||
public float getFrameRate();
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface IggyFlashHeaderInterface extends StructureInterface {
|
||||
|
||||
public long getXMin();
|
||||
|
||||
public long getYMin();
|
||||
|
||||
public long getXMax();
|
||||
|
||||
public long getYMax();
|
||||
|
||||
public float getFrameRate();
|
||||
}
|
||||
|
||||
@@ -1,316 +1,316 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyFont implements StructureInterface {
|
||||
|
||||
public static final int ID = 0xFF16;
|
||||
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int type; //stejny pro rozdilne fonty
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int fontId;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
|
||||
byte[] zeroone; // stejny pro rozdilne fonty
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int char_count2;
|
||||
@IggyFieldType(value = DataType.uint16_t)
|
||||
int ascent;
|
||||
@IggyFieldType(value = DataType.uint16_t)
|
||||
int descent;
|
||||
@IggyFieldType(value = DataType.uint16_t)
|
||||
int leading;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long flags;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_char_struct;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_char_index;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_scale;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long kern_count;
|
||||
@IggyArrayFieldType(value = DataType.float_t, count = 5)
|
||||
float[] unk_float;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_kern;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long what_2;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd_2;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_name;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one_padd;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int xscale;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int yscale;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd_3;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float ssr1;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float ssr2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long char_count;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd_4;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long what_3;
|
||||
@IggyFieldType(value = DataType.uint8_t, count = 272)
|
||||
byte[] zeroes;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss1;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd2;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd3;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss3;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd4;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss4;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd5;
|
||||
|
||||
@IggyFieldType(value = DataType.widechar_t, count = 16)
|
||||
String name;
|
||||
|
||||
List<IggyCharOffset> charOffsets;
|
||||
List<IggyShape> glyphs;
|
||||
IggyCharIndices codePoints;
|
||||
IggyCharAdvances charScales;
|
||||
IggyCharKerning charKernings;
|
||||
|
||||
byte[] padTo4byteBoundary;
|
||||
|
||||
public IggyFont(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int ascent, int descent, int leading, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List<IggyCharOffset> charOffsets, List<IggyShape> chars, IggyCharIndices charIndices, IggyCharAdvances charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) {
|
||||
this.type = type;
|
||||
this.fontId = order_in_iggy_file;
|
||||
this.zeroone = zeroone;
|
||||
this.char_count2 = char_count2;
|
||||
this.ascent = ascent;
|
||||
this.descent = descent;
|
||||
this.leading = leading;
|
||||
this.flags = flags;
|
||||
this.start_of_char_struct = start_of_char_struct;
|
||||
this.start_of_char_index = start_of_char_index;
|
||||
this.start_of_scale = start_of_scale;
|
||||
this.kern_count = kern_count;
|
||||
this.unk_float = unk_float;
|
||||
this.start_of_kern = start_of_kern;
|
||||
this.zero_padd = zero_padd;
|
||||
this.what_2 = what_2;
|
||||
this.zero_padd_2 = zero_padd_2;
|
||||
this.start_of_name = start_of_name;
|
||||
this.one_padd = one_padd;
|
||||
this.xscale = xscale;
|
||||
this.yscale = yscale;
|
||||
this.zero_padd_3 = zero_padd_3;
|
||||
this.ssr1 = ssr1;
|
||||
this.ssr2 = ssr2;
|
||||
this.char_count = char_count;
|
||||
this.zero_padd_4 = zero_padd_4;
|
||||
this.what_3 = what_3;
|
||||
this.zeroes = zeroes;
|
||||
this.sss1 = sss1;
|
||||
this.one_padd2 = one_padd2;
|
||||
this.sss2 = sss2;
|
||||
this.one_padd3 = one_padd3;
|
||||
this.sss3 = sss3;
|
||||
this.one_padd4 = one_padd4;
|
||||
this.sss4 = sss4;
|
||||
this.one_padd5 = one_padd5;
|
||||
this.name = name;
|
||||
this.charOffsets = charOffsets;
|
||||
this.glyphs = chars;
|
||||
this.codePoints = charIndices;
|
||||
this.charScales = charScales;
|
||||
this.charKernings = charKernings;
|
||||
this.padTo4byteBoundary = padTo4byteBoundary;
|
||||
}
|
||||
|
||||
public IggyFont(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
private long readAbsoluteOffset(AbstractDataStream stream) throws IOException {
|
||||
long offset = stream.readUI64();
|
||||
if (offset == 1) {
|
||||
return 0;
|
||||
}
|
||||
return stream.position() - 8 + offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
ByteArrayDataStream s = new ByteArrayDataStream(stream.readBytes((int) (long) stream.available()), stream.is64());
|
||||
type = s.readUI16();
|
||||
fontId = s.readUI16();
|
||||
zeroone = s.readBytes(28);
|
||||
char_count2 = s.readUI16();
|
||||
ascent = s.readUI16();
|
||||
descent = s.readUI16();
|
||||
leading = s.readUI16();
|
||||
flags = s.readUI64();
|
||||
start_of_char_struct = readAbsoluteOffset(s);
|
||||
start_of_char_index = readAbsoluteOffset(s);
|
||||
start_of_scale = readAbsoluteOffset(s);
|
||||
kern_count = s.readUI32();
|
||||
unk_float = new float[5];
|
||||
for (int i = 0; i < unk_float.length; i++) {
|
||||
unk_float[i] = s.readFloat();
|
||||
}
|
||||
start_of_kern = readAbsoluteOffset(s);
|
||||
zero_padd = s.readUI64();
|
||||
what_2 = s.readUI64();
|
||||
zero_padd_2 = s.readUI64();
|
||||
start_of_name = readAbsoluteOffset(s);
|
||||
one_padd = s.readUI64();
|
||||
xscale = s.readUI16();
|
||||
yscale = s.readUI16();
|
||||
zero_padd_3 = s.readUI64();
|
||||
ssr1 = s.readFloat();
|
||||
ssr2 = s.readFloat();
|
||||
char_count = s.readUI32();
|
||||
zero_padd_4 = s.readUI64();
|
||||
what_3 = s.readUI64();
|
||||
s.seek(272, SeekMode.CUR);
|
||||
sss1 = s.readFloat();
|
||||
one_padd2 = s.readUI32();
|
||||
sss2 = s.readFloat();
|
||||
one_padd3 = s.readUI32();
|
||||
sss3 = s.readFloat();
|
||||
one_padd4 = s.readUI32();
|
||||
sss4 = s.readFloat();
|
||||
one_padd5 = s.readUI32();
|
||||
if (start_of_name != 0) {
|
||||
s.seek(start_of_name, SeekMode.SET);
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
int nameCharCnt = 0;
|
||||
do {
|
||||
char c = (char) s.readUI16();
|
||||
nameCharCnt++;
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
nameBuilder.append(c);
|
||||
} while (true);
|
||||
s.seek(32 - nameCharCnt * 2, SeekMode.CUR);
|
||||
name = nameBuilder.toString();
|
||||
}
|
||||
s.readUI64(); //pad zero
|
||||
if (start_of_char_struct != 0) {
|
||||
s.seek(start_of_char_struct, SeekMode.SET);
|
||||
charOffsets = new ArrayList<>();
|
||||
for (int i = 0; i < char_count; i++) {
|
||||
charOffsets.add(new IggyCharOffset(s));
|
||||
}
|
||||
glyphs = new ArrayList<>();
|
||||
for (int i = 0; i < char_count; i++) {
|
||||
long offset = charOffsets.get(i).offset;
|
||||
glyphs.add(new IggyShape(s, offset));
|
||||
}
|
||||
}
|
||||
if (start_of_char_index != 0) {
|
||||
s.seek(start_of_char_index, SeekMode.SET);
|
||||
codePoints = new IggyCharIndices(s, char_count);
|
||||
}
|
||||
if (start_of_scale != 0) {
|
||||
s.seek(start_of_scale, SeekMode.SET);
|
||||
charScales = new IggyCharAdvances(s, char_count);
|
||||
}
|
||||
if (start_of_kern != 0) {
|
||||
s.seek(start_of_kern, SeekMode.SET);
|
||||
charKernings = new IggyCharKerning(s, kern_count);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public long getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int getXscale() {
|
||||
return xscale;
|
||||
}
|
||||
|
||||
public int getYscale() {
|
||||
return yscale;
|
||||
}
|
||||
|
||||
public long getCharacterCount() {
|
||||
return char_count;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<IggyShape> getChars() {
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
public IggyCharIndices getCharIndices() {
|
||||
return codePoints;
|
||||
}
|
||||
|
||||
public IggyCharAdvances getCharAdvances() {
|
||||
return charScales;
|
||||
}
|
||||
|
||||
public IggyCharKerning getCharKernings() {
|
||||
return charKernings;
|
||||
}
|
||||
|
||||
public float[] getUnk_float() {
|
||||
return unk_float;
|
||||
}
|
||||
|
||||
public int getAscent() {
|
||||
return ascent;
|
||||
}
|
||||
|
||||
public int getDescent() {
|
||||
return descent;
|
||||
}
|
||||
|
||||
public int getLeading() {
|
||||
return leading;
|
||||
}
|
||||
|
||||
public long getWhat_2() {
|
||||
return what_2;
|
||||
}
|
||||
|
||||
public long getWhat_3() {
|
||||
return what_3;
|
||||
}
|
||||
|
||||
public List<IggyCharOffset> getCharOffsets() {
|
||||
return charOffsets;
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyFont implements StructureInterface {
|
||||
|
||||
public static final int ID = 0xFF16;
|
||||
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int type; //stejny pro rozdilne fonty
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int fontId;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
|
||||
byte[] zeroone; // stejny pro rozdilne fonty
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int char_count2;
|
||||
@IggyFieldType(value = DataType.uint16_t)
|
||||
int ascent;
|
||||
@IggyFieldType(value = DataType.uint16_t)
|
||||
int descent;
|
||||
@IggyFieldType(value = DataType.uint16_t)
|
||||
int leading;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long flags;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_char_struct;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_char_index;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_scale;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long kern_count;
|
||||
@IggyArrayFieldType(value = DataType.float_t, count = 5)
|
||||
float[] unk_float;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_kern;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long what_2;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd_2;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long start_of_name;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one_padd;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int xscale;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int yscale;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd_3;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float ssr1;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float ssr2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long char_count;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero_padd_4;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long what_3;
|
||||
@IggyFieldType(value = DataType.uint8_t, count = 272)
|
||||
byte[] zeroes;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss1;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd2;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd3;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss3;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd4;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float sss4;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one_padd5;
|
||||
|
||||
@IggyFieldType(value = DataType.widechar_t, count = 16)
|
||||
String name;
|
||||
|
||||
List<IggyCharOffset> charOffsets;
|
||||
List<IggyShape> glyphs;
|
||||
IggyCharIndices codePoints;
|
||||
IggyCharAdvances charScales;
|
||||
IggyCharKerning charKernings;
|
||||
|
||||
byte[] padTo4byteBoundary;
|
||||
|
||||
public IggyFont(int type, int order_in_iggy_file, byte[] zeroone, int char_count2, int ascent, int descent, int leading, long flags, long start_of_char_struct, long start_of_char_index, long start_of_scale, long kern_count, float[] unk_float, long start_of_kern, long zero_padd, long what_2, long zero_padd_2, long start_of_name, long one_padd, int xscale, int yscale, long zero_padd_3, float ssr1, float ssr2, long char_count, long zero_padd_4, long what_3, byte[] zeroes, float sss1, long one_padd2, float sss2, long one_padd3, float sss3, long one_padd4, float sss4, long one_padd5, String name, List<IggyCharOffset> charOffsets, List<IggyShape> chars, IggyCharIndices charIndices, IggyCharAdvances charScales, IggyCharKerning charKernings, byte[] padTo4byteBoundary) {
|
||||
this.type = type;
|
||||
this.fontId = order_in_iggy_file;
|
||||
this.zeroone = zeroone;
|
||||
this.char_count2 = char_count2;
|
||||
this.ascent = ascent;
|
||||
this.descent = descent;
|
||||
this.leading = leading;
|
||||
this.flags = flags;
|
||||
this.start_of_char_struct = start_of_char_struct;
|
||||
this.start_of_char_index = start_of_char_index;
|
||||
this.start_of_scale = start_of_scale;
|
||||
this.kern_count = kern_count;
|
||||
this.unk_float = unk_float;
|
||||
this.start_of_kern = start_of_kern;
|
||||
this.zero_padd = zero_padd;
|
||||
this.what_2 = what_2;
|
||||
this.zero_padd_2 = zero_padd_2;
|
||||
this.start_of_name = start_of_name;
|
||||
this.one_padd = one_padd;
|
||||
this.xscale = xscale;
|
||||
this.yscale = yscale;
|
||||
this.zero_padd_3 = zero_padd_3;
|
||||
this.ssr1 = ssr1;
|
||||
this.ssr2 = ssr2;
|
||||
this.char_count = char_count;
|
||||
this.zero_padd_4 = zero_padd_4;
|
||||
this.what_3 = what_3;
|
||||
this.zeroes = zeroes;
|
||||
this.sss1 = sss1;
|
||||
this.one_padd2 = one_padd2;
|
||||
this.sss2 = sss2;
|
||||
this.one_padd3 = one_padd3;
|
||||
this.sss3 = sss3;
|
||||
this.one_padd4 = one_padd4;
|
||||
this.sss4 = sss4;
|
||||
this.one_padd5 = one_padd5;
|
||||
this.name = name;
|
||||
this.charOffsets = charOffsets;
|
||||
this.glyphs = chars;
|
||||
this.codePoints = charIndices;
|
||||
this.charScales = charScales;
|
||||
this.charKernings = charKernings;
|
||||
this.padTo4byteBoundary = padTo4byteBoundary;
|
||||
}
|
||||
|
||||
public IggyFont(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
private long readAbsoluteOffset(AbstractDataStream stream) throws IOException {
|
||||
long offset = stream.readUI64();
|
||||
if (offset == 1) {
|
||||
return 0;
|
||||
}
|
||||
return stream.position() - 8 + offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
ByteArrayDataStream s = new ByteArrayDataStream(stream.readBytes((int) (long) stream.available()), stream.is64());
|
||||
type = s.readUI16();
|
||||
fontId = s.readUI16();
|
||||
zeroone = s.readBytes(28);
|
||||
char_count2 = s.readUI16();
|
||||
ascent = s.readUI16();
|
||||
descent = s.readUI16();
|
||||
leading = s.readUI16();
|
||||
flags = s.readUI64();
|
||||
start_of_char_struct = readAbsoluteOffset(s);
|
||||
start_of_char_index = readAbsoluteOffset(s);
|
||||
start_of_scale = readAbsoluteOffset(s);
|
||||
kern_count = s.readUI32();
|
||||
unk_float = new float[5];
|
||||
for (int i = 0; i < unk_float.length; i++) {
|
||||
unk_float[i] = s.readFloat();
|
||||
}
|
||||
start_of_kern = readAbsoluteOffset(s);
|
||||
zero_padd = s.readUI64();
|
||||
what_2 = s.readUI64();
|
||||
zero_padd_2 = s.readUI64();
|
||||
start_of_name = readAbsoluteOffset(s);
|
||||
one_padd = s.readUI64();
|
||||
xscale = s.readUI16();
|
||||
yscale = s.readUI16();
|
||||
zero_padd_3 = s.readUI64();
|
||||
ssr1 = s.readFloat();
|
||||
ssr2 = s.readFloat();
|
||||
char_count = s.readUI32();
|
||||
zero_padd_4 = s.readUI64();
|
||||
what_3 = s.readUI64();
|
||||
s.seek(272, SeekMode.CUR);
|
||||
sss1 = s.readFloat();
|
||||
one_padd2 = s.readUI32();
|
||||
sss2 = s.readFloat();
|
||||
one_padd3 = s.readUI32();
|
||||
sss3 = s.readFloat();
|
||||
one_padd4 = s.readUI32();
|
||||
sss4 = s.readFloat();
|
||||
one_padd5 = s.readUI32();
|
||||
if (start_of_name != 0) {
|
||||
s.seek(start_of_name, SeekMode.SET);
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
int nameCharCnt = 0;
|
||||
do {
|
||||
char c = (char) s.readUI16();
|
||||
nameCharCnt++;
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
nameBuilder.append(c);
|
||||
} while (true);
|
||||
s.seek(32 - nameCharCnt * 2, SeekMode.CUR);
|
||||
name = nameBuilder.toString();
|
||||
}
|
||||
s.readUI64(); //pad zero
|
||||
if (start_of_char_struct != 0) {
|
||||
s.seek(start_of_char_struct, SeekMode.SET);
|
||||
charOffsets = new ArrayList<>();
|
||||
for (int i = 0; i < char_count; i++) {
|
||||
charOffsets.add(new IggyCharOffset(s));
|
||||
}
|
||||
glyphs = new ArrayList<>();
|
||||
for (int i = 0; i < char_count; i++) {
|
||||
long offset = charOffsets.get(i).offset;
|
||||
glyphs.add(new IggyShape(s, offset));
|
||||
}
|
||||
}
|
||||
if (start_of_char_index != 0) {
|
||||
s.seek(start_of_char_index, SeekMode.SET);
|
||||
codePoints = new IggyCharIndices(s, char_count);
|
||||
}
|
||||
if (start_of_scale != 0) {
|
||||
s.seek(start_of_scale, SeekMode.SET);
|
||||
charScales = new IggyCharAdvances(s, char_count);
|
||||
}
|
||||
if (start_of_kern != 0) {
|
||||
s.seek(start_of_kern, SeekMode.SET);
|
||||
charKernings = new IggyCharKerning(s, kern_count);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public long getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int getXscale() {
|
||||
return xscale;
|
||||
}
|
||||
|
||||
public int getYscale() {
|
||||
return yscale;
|
||||
}
|
||||
|
||||
public long getCharacterCount() {
|
||||
return char_count;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<IggyShape> getChars() {
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
public IggyCharIndices getCharIndices() {
|
||||
return codePoints;
|
||||
}
|
||||
|
||||
public IggyCharAdvances getCharAdvances() {
|
||||
return charScales;
|
||||
}
|
||||
|
||||
public IggyCharKerning getCharKernings() {
|
||||
return charKernings;
|
||||
}
|
||||
|
||||
public float[] getUnk_float() {
|
||||
return unk_float;
|
||||
}
|
||||
|
||||
public int getAscent() {
|
||||
return ascent;
|
||||
}
|
||||
|
||||
public int getDescent() {
|
||||
return descent;
|
||||
}
|
||||
|
||||
public int getLeading() {
|
||||
return leading;
|
||||
}
|
||||
|
||||
public long getWhat_2() {
|
||||
return what_2;
|
||||
}
|
||||
|
||||
public long getWhat_3() {
|
||||
return what_3;
|
||||
}
|
||||
|
||||
public List<IggyCharOffset> getCharOffsets() {
|
||||
return charOffsets;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,153 +1,153 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* little endian all
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyHeader implements StructureInterface {
|
||||
|
||||
public static long MAGIC = 0xED0A6749;
|
||||
|
||||
//Must be 0xED0A6749
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
private long magic = MAGIC;
|
||||
|
||||
//Assume 0x900
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
private long version;
|
||||
|
||||
//Assuming: 1
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform1;
|
||||
|
||||
//32/64
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform2;
|
||||
|
||||
//Assuming: 1
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform3;
|
||||
|
||||
//Usually: 3
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform4;
|
||||
|
||||
//flags for platform 64?
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
private long unk_0C;
|
||||
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 12)
|
||||
private byte[] reserved;
|
||||
|
||||
@IggyFieldType(value = DataType.uint32_t)
|
||||
private long numSubfiles;
|
||||
|
||||
public IggyHeader(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param version
|
||||
* @param platform1
|
||||
* @param platform2 32/64
|
||||
* @param platform3
|
||||
* @param platform4
|
||||
* @param unk_0C
|
||||
* @param reserved
|
||||
* @param num_subfiles
|
||||
*/
|
||||
public IggyHeader(long version, int platform1, int platform2, int platform3, int platform4, long unk_0C, byte[] reserved, long num_subfiles) {
|
||||
this.version = version;
|
||||
this.platform1 = platform1;
|
||||
this.platform2 = platform2;
|
||||
this.platform3 = platform3;
|
||||
this.platform4 = platform4;
|
||||
this.unk_0C = unk_0C;
|
||||
this.reserved = reserved;
|
||||
this.numSubfiles = num_subfiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
sb.append("version: ").append(version).append(", ");
|
||||
sb.append("platform: ").append(platform1).append(" ").append(platform2).append(" ").append(platform3).append(" ").append(platform4).append(", ");
|
||||
sb.append("unk_0C: ").append(String.format("%08X", unk_0C)).append(", ");
|
||||
sb.append("reserved: 12 bytes").append(", ");
|
||||
sb.append("num_subfiles: ").append(numSubfiles);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
magic = stream.readUI32();
|
||||
if (magic != IggyHeader.MAGIC) {
|
||||
throw new IOException("Invalid Iggy file");
|
||||
}
|
||||
version = stream.readUI32();
|
||||
platform1 = stream.readUI8();
|
||||
platform2 = stream.readUI8(); //32/64
|
||||
platform3 = stream.readUI8();
|
||||
platform4 = stream.readUI8();
|
||||
unk_0C = stream.readUI32();
|
||||
reserved = stream.readBytes(12);
|
||||
numSubfiles = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public boolean is64() {
|
||||
return platform2 == 64;
|
||||
}
|
||||
|
||||
public long getMagic() {
|
||||
return magic;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public int getPlatform1() {
|
||||
return platform1;
|
||||
}
|
||||
|
||||
public int getPlatform2() {
|
||||
return platform2;
|
||||
}
|
||||
|
||||
public int getPlatform3() {
|
||||
return platform3;
|
||||
}
|
||||
|
||||
public int getPlatform4() {
|
||||
return platform4;
|
||||
}
|
||||
|
||||
public long getUnk_0C() {
|
||||
return unk_0C;
|
||||
}
|
||||
|
||||
public byte[] getReserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public long getNumSubfiles() {
|
||||
return numSubfiles;
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* little endian all
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyHeader implements StructureInterface {
|
||||
|
||||
public static long MAGIC = 0xED0A6749;
|
||||
|
||||
//Must be 0xED0A6749
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
private long magic = MAGIC;
|
||||
|
||||
//Assume 0x900
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
private long version;
|
||||
|
||||
//Assuming: 1
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform1;
|
||||
|
||||
//32/64
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform2;
|
||||
|
||||
//Assuming: 1
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform3;
|
||||
|
||||
//Usually: 3
|
||||
@IggyFieldType(value = DataType.uint8_t)
|
||||
private int platform4;
|
||||
|
||||
//flags for platform 64?
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
private long unk_0C;
|
||||
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 12)
|
||||
private byte[] reserved;
|
||||
|
||||
@IggyFieldType(value = DataType.uint32_t)
|
||||
private long numSubfiles;
|
||||
|
||||
public IggyHeader(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param version
|
||||
* @param platform1
|
||||
* @param platform2 32/64
|
||||
* @param platform3
|
||||
* @param platform4
|
||||
* @param unk_0C
|
||||
* @param reserved
|
||||
* @param num_subfiles
|
||||
*/
|
||||
public IggyHeader(long version, int platform1, int platform2, int platform3, int platform4, long unk_0C, byte[] reserved, long num_subfiles) {
|
||||
this.version = version;
|
||||
this.platform1 = platform1;
|
||||
this.platform2 = platform2;
|
||||
this.platform3 = platform3;
|
||||
this.platform4 = platform4;
|
||||
this.unk_0C = unk_0C;
|
||||
this.reserved = reserved;
|
||||
this.numSubfiles = num_subfiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
sb.append("version: ").append(version).append(", ");
|
||||
sb.append("platform: ").append(platform1).append(" ").append(platform2).append(" ").append(platform3).append(" ").append(platform4).append(", ");
|
||||
sb.append("unk_0C: ").append(String.format("%08X", unk_0C)).append(", ");
|
||||
sb.append("reserved: 12 bytes").append(", ");
|
||||
sb.append("num_subfiles: ").append(numSubfiles);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
magic = stream.readUI32();
|
||||
if (magic != IggyHeader.MAGIC) {
|
||||
throw new IOException("Invalid Iggy file");
|
||||
}
|
||||
version = stream.readUI32();
|
||||
platform1 = stream.readUI8();
|
||||
platform2 = stream.readUI8(); //32/64
|
||||
platform3 = stream.readUI8();
|
||||
platform4 = stream.readUI8();
|
||||
unk_0C = stream.readUI32();
|
||||
reserved = stream.readBytes(12);
|
||||
numSubfiles = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public boolean is64() {
|
||||
return platform2 == 64;
|
||||
}
|
||||
|
||||
public long getMagic() {
|
||||
return magic;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public int getPlatform1() {
|
||||
return platform1;
|
||||
}
|
||||
|
||||
public int getPlatform2() {
|
||||
return platform2;
|
||||
}
|
||||
|
||||
public int getPlatform3() {
|
||||
return platform3;
|
||||
}
|
||||
|
||||
public int getPlatform4() {
|
||||
return platform4;
|
||||
}
|
||||
|
||||
public long getUnk_0C() {
|
||||
return unk_0C;
|
||||
}
|
||||
|
||||
public byte[] getReserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public long getNumSubfiles() {
|
||||
return numSubfiles;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,165 +1,165 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*/
|
||||
public class IggyIndexParser {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyIndexParser.class.getName());
|
||||
|
||||
/*
|
||||
Offsets:
|
||||
1) name
|
||||
2) UI16 - zero
|
||||
3) tag list
|
||||
4) ... tag data offsets
|
||||
|
||||
*/
|
||||
/**
|
||||
* Parser for index data. It creates table of indices and table of offsets
|
||||
*
|
||||
* @param indexStream Stream of index
|
||||
* @param indexTableEntry Output index tabke
|
||||
* @param offsets Output list of offsets
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public static void parseIndex(ByteArrayDataStream indexStream, List<Integer> indexTableEntry, List<Long> offsets) throws IOException {
|
||||
int indexTableSize = indexStream.readUI8();
|
||||
int[] indexTable = new int[indexTableSize];
|
||||
for (int i = 0; i < indexTableSize; i++) {
|
||||
int offset = indexStream.readUI8();
|
||||
LOGGER.fine(String.format("index_table_entry: %02x\n", offset));
|
||||
indexTable[i] = offset;
|
||||
indexTableEntry.add(offset);
|
||||
int num = indexStream.readUI8();
|
||||
indexStream.seek(num * 2, SeekMode.CUR);
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
int code;
|
||||
|
||||
while ((code = indexStream.readUI8()) > -1) {
|
||||
LOGGER.finer(String.format("Code = %x\n", code));
|
||||
|
||||
if (code < 0x80) // 0-0x7F
|
||||
{
|
||||
// code is directly an index to the index_table
|
||||
if (code >= indexTableSize) {
|
||||
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x\n", code, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += indexTable[code];
|
||||
} else if (code < 0xC0) // 0x80-BF
|
||||
{
|
||||
int index;
|
||||
|
||||
if ((index = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("< 0xC0: Cannot read index.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= indexTableSize) {
|
||||
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x\n", index, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
int n = code - 0x7F;
|
||||
offset += indexTable[index] * n;
|
||||
} else if (code < 0xD0) // 0xC0-0xCF
|
||||
{
|
||||
offset += ((code * 2) - 0x17E);
|
||||
} else if (code < 0xE0) // 0xD0-0xDF
|
||||
{
|
||||
// Code here depends on plattform[0], we are assuming it is 1, as we checked in load function
|
||||
int i = code & 0xF;
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
if ((n8 = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("< 0xE0: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
|
||||
if (indexStream.is64()) {
|
||||
if (i <= 2) {
|
||||
offset += 8 * n; // Ptr type
|
||||
} else if (i <= 4) {
|
||||
offset += 2 * n;
|
||||
} else if (i == 5) {
|
||||
offset += 4 * n;
|
||||
} else if (i == 6) {
|
||||
offset += 8 * n; // 64 bits type
|
||||
} else {
|
||||
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)\n", i, code));
|
||||
}
|
||||
} else {
|
||||
switch (i) {
|
||||
case 2:
|
||||
offset += 4 * n; // Ptr type
|
||||
break;
|
||||
case 4:
|
||||
offset += 2 * n;
|
||||
break;
|
||||
case 5:
|
||||
offset += 4 * n; // 32 bits type
|
||||
break;
|
||||
case 6:
|
||||
offset += 8 * n;
|
||||
break;
|
||||
default:
|
||||
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)\n", i, code));
|
||||
}
|
||||
}
|
||||
} else if (code == 0xFC) {
|
||||
indexStream.seek(1, SeekMode.CUR);
|
||||
} else if (code == 0xFD) {
|
||||
int n, m;
|
||||
|
||||
if ((n = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read m.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
indexStream.seek(m * 2, SeekMode.CUR);
|
||||
} else if (code == 0xFE) {
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
if ((n8 = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFE: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
offset += n;
|
||||
} else if (code == 0xFF) {
|
||||
long n;
|
||||
|
||||
if ((n = indexStream.readUI32()) < 0) {
|
||||
LOGGER.severe(String.format("0xFF: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
} else {
|
||||
LOGGER.warning(String.format("Unrecognized code: %x\n", code));
|
||||
}
|
||||
|
||||
offsets.add(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*/
|
||||
public class IggyIndexParser {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyIndexParser.class.getName());
|
||||
|
||||
/*
|
||||
Offsets:
|
||||
1) name
|
||||
2) UI16 - zero
|
||||
3) tag list
|
||||
4) ... tag data offsets
|
||||
|
||||
*/
|
||||
/**
|
||||
* Parser for index data. It creates table of indices and table of offsets
|
||||
*
|
||||
* @param indexStream Stream of index
|
||||
* @param indexTableEntry Output index tabke
|
||||
* @param offsets Output list of offsets
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public static void parseIndex(ByteArrayDataStream indexStream, List<Integer> indexTableEntry, List<Long> offsets) throws IOException {
|
||||
int indexTableSize = indexStream.readUI8();
|
||||
int[] indexTable = new int[indexTableSize];
|
||||
for (int i = 0; i < indexTableSize; i++) {
|
||||
int offset = indexStream.readUI8();
|
||||
LOGGER.fine(String.format("index_table_entry: %02x\n", offset));
|
||||
indexTable[i] = offset;
|
||||
indexTableEntry.add(offset);
|
||||
int num = indexStream.readUI8();
|
||||
indexStream.seek(num * 2, SeekMode.CUR);
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
int code;
|
||||
|
||||
while ((code = indexStream.readUI8()) > -1) {
|
||||
LOGGER.finer(String.format("Code = %x\n", code));
|
||||
|
||||
if (code < 0x80) // 0-0x7F
|
||||
{
|
||||
// code is directly an index to the index_table
|
||||
if (code >= indexTableSize) {
|
||||
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x\n", code, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += indexTable[code];
|
||||
} else if (code < 0xC0) // 0x80-BF
|
||||
{
|
||||
int index;
|
||||
|
||||
if ((index = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("< 0xC0: Cannot read index.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= indexTableSize) {
|
||||
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x\n", index, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
int n = code - 0x7F;
|
||||
offset += indexTable[index] * n;
|
||||
} else if (code < 0xD0) // 0xC0-0xCF
|
||||
{
|
||||
offset += ((code * 2) - 0x17E);
|
||||
} else if (code < 0xE0) // 0xD0-0xDF
|
||||
{
|
||||
// Code here depends on plattform[0], we are assuming it is 1, as we checked in load function
|
||||
int i = code & 0xF;
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
if ((n8 = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("< 0xE0: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
|
||||
if (indexStream.is64()) {
|
||||
if (i <= 2) {
|
||||
offset += 8 * n; // Ptr type
|
||||
} else if (i <= 4) {
|
||||
offset += 2 * n;
|
||||
} else if (i == 5) {
|
||||
offset += 4 * n;
|
||||
} else if (i == 6) {
|
||||
offset += 8 * n; // 64 bits type
|
||||
} else {
|
||||
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)\n", i, code));
|
||||
}
|
||||
} else {
|
||||
switch (i) {
|
||||
case 2:
|
||||
offset += 4 * n; // Ptr type
|
||||
break;
|
||||
case 4:
|
||||
offset += 2 * n;
|
||||
break;
|
||||
case 5:
|
||||
offset += 4 * n; // 32 bits type
|
||||
break;
|
||||
case 6:
|
||||
offset += 8 * n;
|
||||
break;
|
||||
default:
|
||||
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)\n", i, code));
|
||||
}
|
||||
}
|
||||
} else if (code == 0xFC) {
|
||||
indexStream.seek(1, SeekMode.CUR);
|
||||
} else if (code == 0xFD) {
|
||||
int n, m;
|
||||
|
||||
if ((n = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read m.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
indexStream.seek(m * 2, SeekMode.CUR);
|
||||
} else if (code == 0xFE) {
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
if ((n8 = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFE: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
offset += n;
|
||||
} else if (code == 0xFF) {
|
||||
long n;
|
||||
|
||||
if ((n = indexStream.readUI32()) < 0) {
|
||||
LOGGER.severe(String.format("0xFF: Cannot read n.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
} else {
|
||||
LOGGER.warning(String.format("Unrecognized code: %x\n", code));
|
||||
}
|
||||
|
||||
offsets.add(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,155 +1,155 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShape implements StructureInterface {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyShape.class.getName());
|
||||
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float minx; //bearing X - this is the horizontal distance from the current pen position to the glyph's left bbox edge.
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float miny; //bearing Y - this is the vertical distance from the baseline to the top of the glyph's bbox.
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float maxx; //advanceX - bearingX
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float maxy; //advanceY - bearingY
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk; // stejny vetsinou - napr. 48 - JP: to by mohlo byt advance
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long count;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one; // 1
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one2; // 1
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one3; // 1
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one4; // 1
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long two1; // 2
|
||||
|
||||
public float getBearingX() {
|
||||
return minx;
|
||||
}
|
||||
|
||||
public float getBearingY() {
|
||||
return miny;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return maxx - minx;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return maxy - miny;
|
||||
}
|
||||
|
||||
List<IggyShapeNode> nodes;
|
||||
|
||||
private long offset;
|
||||
|
||||
public IggyShape(AbstractDataStream stream, long offset) throws IOException {
|
||||
this.offset = offset;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyShape(float minx, float miny, float maxx, float maxy, long advance, long count, long one, long one2, long one3, long one4, long two1, List<IggyShapeNode> nodes) {
|
||||
this.minx = minx;
|
||||
this.miny = miny;
|
||||
this.maxx = maxx;
|
||||
this.maxy = maxy;
|
||||
this.unk = advance;
|
||||
this.count = count;
|
||||
this.one = one;
|
||||
this.one2 = one2;
|
||||
this.one3 = one3;
|
||||
this.one4 = one4;
|
||||
this.two1 = two1;
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream s) throws IOException {
|
||||
s.seek(offset, SeekMode.SET);
|
||||
minx = s.readFloat();
|
||||
miny = s.readFloat();
|
||||
maxx = s.readFloat();
|
||||
maxy = s.readFloat();
|
||||
unk = s.readUI64();
|
||||
count = s.readUI64();
|
||||
one = s.readUI64();
|
||||
one2 = s.readUI64();
|
||||
one3 = s.readUI64();
|
||||
one4 = s.readUI32();
|
||||
two1 = s.readUI32();
|
||||
|
||||
if ((one != 1) || (one2 != 1) || (one3 != 1) || (one4 != 1) || (two1 != 2)) {
|
||||
LOGGER.fine(String.format("Unique header at pos %d, one: %d, one2: %d, one3: %d, one4: %d, two1: %d\n", offset, one, one2, one3, one4, two1));
|
||||
}
|
||||
|
||||
nodes = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
nodes.add(new IggyShapeNode(s, i == 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public float getMinx() {
|
||||
return minx;
|
||||
}
|
||||
|
||||
public float getMiny() {
|
||||
return miny;
|
||||
}
|
||||
|
||||
public float getMaxx() {
|
||||
return maxx;
|
||||
}
|
||||
|
||||
public float getMaxy() {
|
||||
return maxy;
|
||||
}
|
||||
|
||||
public long getUnk() {
|
||||
return unk;
|
||||
}
|
||||
|
||||
public long getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public long getOne2() {
|
||||
return one2;
|
||||
}
|
||||
|
||||
public long getOne3() {
|
||||
return one3;
|
||||
}
|
||||
|
||||
public long getOne4() {
|
||||
return one4;
|
||||
}
|
||||
|
||||
public long getTwo1() {
|
||||
return two1;
|
||||
}
|
||||
|
||||
public List<IggyShapeNode> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShape implements StructureInterface {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyShape.class.getName());
|
||||
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float minx; //bearing X - this is the horizontal distance from the current pen position to the glyph's left bbox edge.
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float miny; //bearing Y - this is the vertical distance from the baseline to the top of the glyph's bbox.
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float maxx; //advanceX - bearingX
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float maxy; //advanceY - bearingY
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk; // stejny vetsinou - napr. 48 - JP: to by mohlo byt advance
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long count;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one; // 1
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one2; // 1
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one3; // 1
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long one4; // 1
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long two1; // 2
|
||||
|
||||
public float getBearingX() {
|
||||
return minx;
|
||||
}
|
||||
|
||||
public float getBearingY() {
|
||||
return miny;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return maxx - minx;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return maxy - miny;
|
||||
}
|
||||
|
||||
List<IggyShapeNode> nodes;
|
||||
|
||||
private long offset;
|
||||
|
||||
public IggyShape(AbstractDataStream stream, long offset) throws IOException {
|
||||
this.offset = offset;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyShape(float minx, float miny, float maxx, float maxy, long advance, long count, long one, long one2, long one3, long one4, long two1, List<IggyShapeNode> nodes) {
|
||||
this.minx = minx;
|
||||
this.miny = miny;
|
||||
this.maxx = maxx;
|
||||
this.maxy = maxy;
|
||||
this.unk = advance;
|
||||
this.count = count;
|
||||
this.one = one;
|
||||
this.one2 = one2;
|
||||
this.one3 = one3;
|
||||
this.one4 = one4;
|
||||
this.two1 = two1;
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream s) throws IOException {
|
||||
s.seek(offset, SeekMode.SET);
|
||||
minx = s.readFloat();
|
||||
miny = s.readFloat();
|
||||
maxx = s.readFloat();
|
||||
maxy = s.readFloat();
|
||||
unk = s.readUI64();
|
||||
count = s.readUI64();
|
||||
one = s.readUI64();
|
||||
one2 = s.readUI64();
|
||||
one3 = s.readUI64();
|
||||
one4 = s.readUI32();
|
||||
two1 = s.readUI32();
|
||||
|
||||
if ((one != 1) || (one2 != 1) || (one3 != 1) || (one4 != 1) || (two1 != 2)) {
|
||||
LOGGER.fine(String.format("Unique header at pos %d, one: %d, one2: %d, one3: %d, one4: %d, two1: %d\n", offset, one, one2, one3, one4, two1));
|
||||
}
|
||||
|
||||
nodes = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
nodes.add(new IggyShapeNode(s, i == 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public float getMinx() {
|
||||
return minx;
|
||||
}
|
||||
|
||||
public float getMiny() {
|
||||
return miny;
|
||||
}
|
||||
|
||||
public float getMaxx() {
|
||||
return maxx;
|
||||
}
|
||||
|
||||
public float getMaxy() {
|
||||
return maxy;
|
||||
}
|
||||
|
||||
public long getUnk() {
|
||||
return unk;
|
||||
}
|
||||
|
||||
public long getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public long getOne2() {
|
||||
return one2;
|
||||
}
|
||||
|
||||
public long getOne3() {
|
||||
return one3;
|
||||
}
|
||||
|
||||
public long getOne4() {
|
||||
return one4;
|
||||
}
|
||||
|
||||
public long getTwo1() {
|
||||
return two1;
|
||||
}
|
||||
|
||||
public List<IggyShapeNode> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,122 +1,122 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShapeNode implements StructureInterface {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyShapeNode.class.getName());
|
||||
|
||||
public static int NODE_TYPE_MOVE = 1;
|
||||
public static int NODE_TYPE_LINE_TO = 2;
|
||||
public static int NODE_TYPE_CURVE_POINT = 3;
|
||||
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float targetX;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float targetY; // negative
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float controlX; // for curves
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float controlY; // for curves, negative
|
||||
@IggyFieldType(DataType.uint8_t) //1-moveto, 2-lineto , 3 - curve to
|
||||
int node_type;
|
||||
@IggyFieldType(DataType.uint8_t) // 208 start smooth (for j=1 only), 61 smooth interupt (muze a nemusi byt pro novy oddeleny kus charu - kdyz je subtype predchoziho vetsi nez 0 (kupr 5) bude pro oddeleny usek 61, jinak pokud je subtype predchoziho 0 bude pro oddeleny usek 0)
|
||||
int node_subtype;
|
||||
@IggyFieldType(DataType.uint8_t)
|
||||
int zer1;
|
||||
@IggyFieldType(DataType.uint8_t)
|
||||
int zer2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long isstart; // 1 v prubehu nebo 0 pouze pro prvni (i kdyz jsou delene jako dvojtecka!!!)
|
||||
|
||||
private boolean first;
|
||||
|
||||
public IggyShapeNode(float x1, float y1, float x2, float y2, int node_type, int node_subtype, int zer1, int zer2, long isstart) {
|
||||
this.targetX = x1;
|
||||
this.targetY = y1;
|
||||
this.controlX = x2;
|
||||
this.controlY = y2;
|
||||
this.node_type = node_type;
|
||||
this.node_subtype = node_subtype;
|
||||
this.zer1 = zer1;
|
||||
this.zer2 = zer2;
|
||||
this.isstart = isstart;
|
||||
}
|
||||
|
||||
public IggyShapeNode(AbstractDataStream s, boolean first) throws IOException {
|
||||
this.first = first;
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream s) throws IOException {
|
||||
targetX = s.readFloat();
|
||||
targetY = s.readFloat();
|
||||
controlX = s.readFloat();
|
||||
controlY = s.readFloat();
|
||||
node_type = s.readUI8();
|
||||
node_subtype = s.readUI8();
|
||||
zer1 = s.readUI8();
|
||||
zer2 = s.readUI8();
|
||||
isstart = s.readUI32();
|
||||
|
||||
if ((zer1 != 0) | (zer2 != 0)) {
|
||||
LOGGER.fine(String.format("Unknown zeroes at pos %08X\n", s.position() - 6));
|
||||
}
|
||||
if ((!first) & (isstart != 1)) {
|
||||
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
|
||||
}
|
||||
if ((first) & (isstart != 0)) {
|
||||
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public float getX1() {
|
||||
return targetX;
|
||||
}
|
||||
|
||||
public float getY1() {
|
||||
return targetY;
|
||||
}
|
||||
|
||||
public float getX2() {
|
||||
return controlX;
|
||||
}
|
||||
|
||||
public float getY2() {
|
||||
return controlY;
|
||||
}
|
||||
|
||||
public int getNodeType() {
|
||||
return node_type;
|
||||
}
|
||||
|
||||
public int getNodeSubType() {
|
||||
return node_subtype;
|
||||
}
|
||||
|
||||
public int getZer1() {
|
||||
return zer1;
|
||||
}
|
||||
|
||||
public int getZer2() {
|
||||
return zer2;
|
||||
}
|
||||
|
||||
public boolean isStart() {
|
||||
return isstart == 1;
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShapeNode implements StructureInterface {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyShapeNode.class.getName());
|
||||
|
||||
public static int NODE_TYPE_MOVE = 1;
|
||||
public static int NODE_TYPE_LINE_TO = 2;
|
||||
public static int NODE_TYPE_CURVE_POINT = 3;
|
||||
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float targetX;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float targetY; // negative
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float controlX; // for curves
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float controlY; // for curves, negative
|
||||
@IggyFieldType(DataType.uint8_t) //1-moveto, 2-lineto , 3 - curve to
|
||||
int node_type;
|
||||
@IggyFieldType(DataType.uint8_t) // 208 start smooth (for j=1 only), 61 smooth interupt (muze a nemusi byt pro novy oddeleny kus charu - kdyz je subtype predchoziho vetsi nez 0 (kupr 5) bude pro oddeleny usek 61, jinak pokud je subtype predchoziho 0 bude pro oddeleny usek 0)
|
||||
int node_subtype;
|
||||
@IggyFieldType(DataType.uint8_t)
|
||||
int zer1;
|
||||
@IggyFieldType(DataType.uint8_t)
|
||||
int zer2;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long isstart; // 1 v prubehu nebo 0 pouze pro prvni (i kdyz jsou delene jako dvojtecka!!!)
|
||||
|
||||
private boolean first;
|
||||
|
||||
public IggyShapeNode(float x1, float y1, float x2, float y2, int node_type, int node_subtype, int zer1, int zer2, long isstart) {
|
||||
this.targetX = x1;
|
||||
this.targetY = y1;
|
||||
this.controlX = x2;
|
||||
this.controlY = y2;
|
||||
this.node_type = node_type;
|
||||
this.node_subtype = node_subtype;
|
||||
this.zer1 = zer1;
|
||||
this.zer2 = zer2;
|
||||
this.isstart = isstart;
|
||||
}
|
||||
|
||||
public IggyShapeNode(AbstractDataStream s, boolean first) throws IOException {
|
||||
this.first = first;
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream s) throws IOException {
|
||||
targetX = s.readFloat();
|
||||
targetY = s.readFloat();
|
||||
controlX = s.readFloat();
|
||||
controlY = s.readFloat();
|
||||
node_type = s.readUI8();
|
||||
node_subtype = s.readUI8();
|
||||
zer1 = s.readUI8();
|
||||
zer2 = s.readUI8();
|
||||
isstart = s.readUI32();
|
||||
|
||||
if ((zer1 != 0) | (zer2 != 0)) {
|
||||
LOGGER.fine(String.format("Unknown zeroes at pos %08X\n", s.position() - 6));
|
||||
}
|
||||
if ((!first) & (isstart != 1)) {
|
||||
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
|
||||
}
|
||||
if ((first) & (isstart != 0)) {
|
||||
LOGGER.fine(String.format("Unknown format at pos %08X\n", s.position() - 4));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public float getX1() {
|
||||
return targetX;
|
||||
}
|
||||
|
||||
public float getY1() {
|
||||
return targetY;
|
||||
}
|
||||
|
||||
public float getX2() {
|
||||
return controlX;
|
||||
}
|
||||
|
||||
public float getY2() {
|
||||
return controlY;
|
||||
}
|
||||
|
||||
public int getNodeType() {
|
||||
return node_type;
|
||||
}
|
||||
|
||||
public int getNodeSubType() {
|
||||
return node_subtype;
|
||||
}
|
||||
|
||||
public int getZer1() {
|
||||
return zer1;
|
||||
}
|
||||
|
||||
public int getZer2() {
|
||||
return zer2;
|
||||
}
|
||||
|
||||
public boolean isStart() {
|
||||
return isstart == 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggySubFileEntry implements StructureInterface {
|
||||
|
||||
public static final int TYPE_INDEX = 0;
|
||||
public static final int TYPE_FLASH = 1;
|
||||
|
||||
@SWFType(BasicType.UI32)
|
||||
long type;
|
||||
|
||||
@SWFType(BasicType.UI32)
|
||||
long size;
|
||||
|
||||
//apparently same as size, maybe (un)compressed (?)
|
||||
@SWFType(BasicType.UI32)
|
||||
long size2;
|
||||
|
||||
//absolute offset
|
||||
@SWFType(BasicType.UI32)
|
||||
long offset;
|
||||
|
||||
public IggySubFileEntry(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggySubFileEntry(long type, long size, long size2, long offset) {
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
this.size2 = size2;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
sb.append("id: ").append(type).append(", ");
|
||||
sb.append("size: ").append(size).append(", ");
|
||||
sb.append("size2: ").append(size2).append(", ");
|
||||
sb.append("offset: ").append(offset);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
type = stream.readUI32();
|
||||
size = stream.readUI32();
|
||||
size2 = stream.readUI32();
|
||||
offset = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggySubFileEntry implements StructureInterface {
|
||||
|
||||
public static final int TYPE_INDEX = 0;
|
||||
public static final int TYPE_FLASH = 1;
|
||||
|
||||
@SWFType(BasicType.UI32)
|
||||
long type;
|
||||
|
||||
@SWFType(BasicType.UI32)
|
||||
long size;
|
||||
|
||||
//apparently same as size, maybe (un)compressed (?)
|
||||
@SWFType(BasicType.UI32)
|
||||
long size2;
|
||||
|
||||
//absolute offset
|
||||
@SWFType(BasicType.UI32)
|
||||
long offset;
|
||||
|
||||
public IggySubFileEntry(AbstractDataStream stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggySubFileEntry(long type, long size, long size2, long offset) {
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
this.size2 = size2;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
sb.append("id: ").append(type).append(", ");
|
||||
sb.append("size: ").append(size).append(", ");
|
||||
sb.append("size2: ").append(size2).append(", ");
|
||||
sb.append("offset: ").append(offset);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException {
|
||||
type = stream.readUI32();
|
||||
size = stream.readUI32();
|
||||
size2 = stream.readUI32();
|
||||
offset = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,194 +1,194 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyText implements StructureInterface {
|
||||
|
||||
public static final int ID = 0xFF06;
|
||||
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int type; // Tag type
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int textIndex;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
|
||||
byte zeroone[];
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par1;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par2;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par3;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par4;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int enum_hex;
|
||||
|
||||
//Guessed
|
||||
boolean hasText;
|
||||
boolean wordWrap;
|
||||
boolean multiline;
|
||||
boolean password;
|
||||
boolean readOnly;
|
||||
boolean hasTextColor;
|
||||
boolean hasMaxLength;
|
||||
boolean hasFont;
|
||||
boolean hasFontClass;
|
||||
boolean autosize;
|
||||
boolean hasLayout;
|
||||
boolean noSelect;
|
||||
boolean border;
|
||||
boolean wasStatic;
|
||||
boolean html;
|
||||
boolean useOutlines;
|
||||
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int fontIndex;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 32)
|
||||
byte[] some; // same for different fonts
|
||||
@IggyArrayFieldType(value = DataType.widechar_t)
|
||||
String initialText; //till end of info file?
|
||||
|
||||
public IggyText(int type, int order_in_iggy_file, byte[] zeroone, float par1, float par2, float par3, float par4, int enum_hex, int for_which_font_order_in_iggyfile, long zero, long one, byte[] some, long offset_of_name, String name) {
|
||||
this.type = type;
|
||||
this.textIndex = order_in_iggy_file;
|
||||
this.zeroone = zeroone;
|
||||
this.par1 = par1;
|
||||
this.par2 = par2;
|
||||
this.par3 = par3;
|
||||
this.par4 = par4;
|
||||
this.enum_hex = enum_hex;
|
||||
this.fontIndex = for_which_font_order_in_iggyfile;
|
||||
this.zero = zero;
|
||||
this.one = one;
|
||||
this.some = some;
|
||||
this.initialText = name;
|
||||
}
|
||||
|
||||
public IggyText(AbstractDataStream stream) throws IOException {
|
||||
this.readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream s) throws IOException {
|
||||
|
||||
type = s.readUI16();
|
||||
//characterId - iggy Id
|
||||
textIndex = s.readUI16();
|
||||
zeroone = s.readBytes(28);
|
||||
|
||||
//bounds?:
|
||||
par1 = s.readFloat();
|
||||
par2 = s.readFloat();
|
||||
par3 = s.readFloat();
|
||||
par4 = s.readFloat();
|
||||
|
||||
//flags
|
||||
enum_hex = s.readUI16();
|
||||
|
||||
int en = enum_hex;
|
||||
|
||||
//guessing - it could be like DefineEditText?...
|
||||
hasText = ((en >> 0) & 1) == 1;
|
||||
wordWrap = ((en >> 1) & 1) == 1;
|
||||
multiline = ((en >> 2) & 1) == 1;
|
||||
password = ((en >> 3) & 1) == 1;
|
||||
readOnly = ((en >> 4) & 1) == 1;
|
||||
hasTextColor = ((en >> 5) & 1) == 1;
|
||||
hasMaxLength = ((en >> 6) & 1) == 1;
|
||||
hasFont = ((en >> 7) & 1) == 1;
|
||||
hasFontClass = ((en >> 8) & 1) == 1;
|
||||
autosize = ((en >> 9) & 1) == 1;
|
||||
hasLayout = ((en >> 10) & 1) == 1;
|
||||
noSelect = ((en >> 11) & 1) == 1;
|
||||
border = ((en >> 12) & 1) == 1;
|
||||
wasStatic = ((en >> 13) & 1) == 1;
|
||||
html = ((en >> 14) & 1) == 1;
|
||||
useOutlines = ((en >> 15) & 1) == 1;
|
||||
|
||||
//if hasFont?
|
||||
fontIndex = s.readUI16(); //fontId
|
||||
//if hasFontClass - readString?
|
||||
//if hasFont || hasFontClass - readFontHeight?
|
||||
//if hasTextColor....?
|
||||
zero = s.readUI32();
|
||||
one = s.readUI64(); //01CB FF33 3333
|
||||
some = s.readBytes(32); // [6] => 40, [24] => 8
|
||||
StringBuilder textBuilder = new StringBuilder();
|
||||
do {
|
||||
char c = (char) s.readUI16();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
textBuilder.append(c);
|
||||
} while (true);
|
||||
initialText = textBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getTextIndex() {
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
public byte[] getZeroone() {
|
||||
return zeroone;
|
||||
}
|
||||
|
||||
public float getPar1() {
|
||||
return par1;
|
||||
}
|
||||
|
||||
public float getPar2() {
|
||||
return par2;
|
||||
}
|
||||
|
||||
public float getPar3() {
|
||||
return par3;
|
||||
}
|
||||
|
||||
public float getPar4() {
|
||||
return par4;
|
||||
}
|
||||
|
||||
public int getEnum_hex() {
|
||||
return enum_hex;
|
||||
}
|
||||
|
||||
public int getFontIndex() {
|
||||
return fontIndex;
|
||||
}
|
||||
|
||||
public long getZero() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
public long getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public byte[] getSome() {
|
||||
return some;
|
||||
}
|
||||
|
||||
public String getInitialText() {
|
||||
return initialText;
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyText implements StructureInterface {
|
||||
|
||||
public static final int ID = 0xFF06;
|
||||
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int type; // Tag type
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int textIndex;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 28)
|
||||
byte zeroone[];
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par1;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par2;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par3;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float par4;
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int enum_hex;
|
||||
|
||||
//Guessed
|
||||
boolean hasText;
|
||||
boolean wordWrap;
|
||||
boolean multiline;
|
||||
boolean password;
|
||||
boolean readOnly;
|
||||
boolean hasTextColor;
|
||||
boolean hasMaxLength;
|
||||
boolean hasFont;
|
||||
boolean hasFontClass;
|
||||
boolean autosize;
|
||||
boolean hasLayout;
|
||||
boolean noSelect;
|
||||
boolean border;
|
||||
boolean wasStatic;
|
||||
boolean html;
|
||||
boolean useOutlines;
|
||||
|
||||
@IggyFieldType(DataType.uint16_t)
|
||||
int fontIndex;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 32)
|
||||
byte[] some; // same for different fonts
|
||||
@IggyArrayFieldType(value = DataType.widechar_t)
|
||||
String initialText; //till end of info file?
|
||||
|
||||
public IggyText(int type, int order_in_iggy_file, byte[] zeroone, float par1, float par2, float par3, float par4, int enum_hex, int for_which_font_order_in_iggyfile, long zero, long one, byte[] some, long offset_of_name, String name) {
|
||||
this.type = type;
|
||||
this.textIndex = order_in_iggy_file;
|
||||
this.zeroone = zeroone;
|
||||
this.par1 = par1;
|
||||
this.par2 = par2;
|
||||
this.par3 = par3;
|
||||
this.par4 = par4;
|
||||
this.enum_hex = enum_hex;
|
||||
this.fontIndex = for_which_font_order_in_iggyfile;
|
||||
this.zero = zero;
|
||||
this.one = one;
|
||||
this.some = some;
|
||||
this.initialText = name;
|
||||
}
|
||||
|
||||
public IggyText(AbstractDataStream stream) throws IOException {
|
||||
this.readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(AbstractDataStream s) throws IOException {
|
||||
|
||||
type = s.readUI16();
|
||||
//characterId - iggy Id
|
||||
textIndex = s.readUI16();
|
||||
zeroone = s.readBytes(28);
|
||||
|
||||
//bounds?:
|
||||
par1 = s.readFloat();
|
||||
par2 = s.readFloat();
|
||||
par3 = s.readFloat();
|
||||
par4 = s.readFloat();
|
||||
|
||||
//flags
|
||||
enum_hex = s.readUI16();
|
||||
|
||||
int en = enum_hex;
|
||||
|
||||
//guessing - it could be like DefineEditText?...
|
||||
hasText = ((en >> 0) & 1) == 1;
|
||||
wordWrap = ((en >> 1) & 1) == 1;
|
||||
multiline = ((en >> 2) & 1) == 1;
|
||||
password = ((en >> 3) & 1) == 1;
|
||||
readOnly = ((en >> 4) & 1) == 1;
|
||||
hasTextColor = ((en >> 5) & 1) == 1;
|
||||
hasMaxLength = ((en >> 6) & 1) == 1;
|
||||
hasFont = ((en >> 7) & 1) == 1;
|
||||
hasFontClass = ((en >> 8) & 1) == 1;
|
||||
autosize = ((en >> 9) & 1) == 1;
|
||||
hasLayout = ((en >> 10) & 1) == 1;
|
||||
noSelect = ((en >> 11) & 1) == 1;
|
||||
border = ((en >> 12) & 1) == 1;
|
||||
wasStatic = ((en >> 13) & 1) == 1;
|
||||
html = ((en >> 14) & 1) == 1;
|
||||
useOutlines = ((en >> 15) & 1) == 1;
|
||||
|
||||
//if hasFont?
|
||||
fontIndex = s.readUI16(); //fontId
|
||||
//if hasFontClass - readString?
|
||||
//if hasFont || hasFontClass - readFontHeight?
|
||||
//if hasTextColor....?
|
||||
zero = s.readUI32();
|
||||
one = s.readUI64(); //01CB FF33 3333
|
||||
some = s.readBytes(32); // [6] => 40, [24] => 8
|
||||
StringBuilder textBuilder = new StringBuilder();
|
||||
do {
|
||||
char c = (char) s.readUI16();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
textBuilder.append(c);
|
||||
} while (true);
|
||||
initialText = textBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getTextIndex() {
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
public byte[] getZeroone() {
|
||||
return zeroone;
|
||||
}
|
||||
|
||||
public float getPar1() {
|
||||
return par1;
|
||||
}
|
||||
|
||||
public float getPar2() {
|
||||
return par2;
|
||||
}
|
||||
|
||||
public float getPar3() {
|
||||
return par3;
|
||||
}
|
||||
|
||||
public float getPar4() {
|
||||
return par4;
|
||||
}
|
||||
|
||||
public int getEnum_hex() {
|
||||
return enum_hex;
|
||||
}
|
||||
|
||||
public int getFontIndex() {
|
||||
return fontIndex;
|
||||
}
|
||||
|
||||
public long getZero() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
public long getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public byte[] getSome() {
|
||||
return some;
|
||||
}
|
||||
|
||||
public String getInitialText() {
|
||||
return initialText;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*/
|
||||
public enum SeekMode {
|
||||
SET, CUR, END
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*/
|
||||
public enum SeekMode {
|
||||
SET, CUR, END
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface StructureInterface {
|
||||
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException;
|
||||
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException;
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface StructureInterface {
|
||||
|
||||
public void readFromDataStream(AbstractDataStream stream) throws IOException;
|
||||
|
||||
public void writeToDataStream(AbstractDataStream stream) throws IOException;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
package com.jpexs.decompiler.flash.iggy.annotations;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.DataType;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author JPEXS
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface IggyArrayFieldType {
|
||||
|
||||
/// Type of value
|
||||
DataType value() default DataType.unknown;
|
||||
|
||||
int count() default -1;
|
||||
|
||||
/// Field name on which Count depends
|
||||
String countField() default "";
|
||||
|
||||
//Count to add to countField
|
||||
int countAdd() default 0;
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.annotations;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.DataType;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author JPEXS
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface IggyArrayFieldType {
|
||||
|
||||
/// Type of value
|
||||
DataType value() default DataType.unknown;
|
||||
|
||||
int count() default -1;
|
||||
|
||||
/// Field name on which Count depends
|
||||
String countField() default "";
|
||||
|
||||
//Count to add to countField
|
||||
int countAdd() default 0;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
package com.jpexs.decompiler.flash.iggy.annotations;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.DataType;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface IggyFieldType {
|
||||
|
||||
/// Type of value
|
||||
DataType value() default DataType.unknown;
|
||||
|
||||
/// Alternate type when condition is met
|
||||
DataType alternateValue() default DataType.unknown;
|
||||
|
||||
/// Condition for alternate type
|
||||
String alternateCondition() default "";
|
||||
|
||||
/// Count - used primarily for bit fields UB,SB,FB to specify number of bits
|
||||
int count() default -1;
|
||||
|
||||
/// Field name on which Count depends
|
||||
String countField() default "";
|
||||
|
||||
//Count to add to countField
|
||||
int countAdd() default 0;
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.annotations;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.DataType;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface IggyFieldType {
|
||||
|
||||
/// Type of value
|
||||
DataType value() default DataType.unknown;
|
||||
|
||||
/// Alternate type when condition is met
|
||||
DataType alternateValue() default DataType.unknown;
|
||||
|
||||
/// Condition for alternate type
|
||||
String alternateCondition() default "";
|
||||
|
||||
/// Count - used primarily for bit fields UB,SB,FB to specify number of bits
|
||||
int count() default -1;
|
||||
|
||||
/// Field name on which Count depends
|
||||
String countField() default "";
|
||||
|
||||
//Count to add to countField
|
||||
int countAdd() default 0;
|
||||
}
|
||||
|
||||
@@ -1,105 +1,105 @@
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLE;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShapeToSwfConvertor {
|
||||
|
||||
private static int makeLengthsEmX(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
private static int makeLengthsEmY(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
public static SHAPE convertCharToShape(IggyShape igchar) {
|
||||
SHAPE shape = new SHAPE();
|
||||
List<SHAPERECORD> retList = new ArrayList<>();
|
||||
List<IggyShapeNode> ignodes = igchar.getNodes();
|
||||
|
||||
int prevX = 0;
|
||||
int prevY = 0;
|
||||
|
||||
for (IggyShapeNode ign : ignodes) {
|
||||
if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_MOVE) {
|
||||
StyleChangeRecord scr = new StyleChangeRecord();
|
||||
scr.stateMoveTo = true;
|
||||
prevX = scr.moveDeltaX = makeLengthsEmX(ign.getX1());
|
||||
prevY = scr.moveDeltaY = makeLengthsEmY(ign.getY1());
|
||||
scr.fillStyles = new FILLSTYLEARRAY();
|
||||
scr.lineStyles = new LINESTYLEARRAY();
|
||||
scr.calculateBits();
|
||||
retList.add(scr);
|
||||
} else {
|
||||
|
||||
int curX1 = makeLengthsEmX(ign.getX1());
|
||||
int curY1 = makeLengthsEmY(ign.getY1());
|
||||
|
||||
int curX2 = makeLengthsEmX(ign.getX2());
|
||||
int curY2 = makeLengthsEmY(ign.getY2());
|
||||
|
||||
if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_LINE_TO) {
|
||||
StraightEdgeRecord ser = new StraightEdgeRecord();
|
||||
ser.deltaX = curX1 - prevX;
|
||||
ser.deltaY = curY1 - prevY;
|
||||
ser.generalLineFlag = true;
|
||||
ser.simplify();
|
||||
ser.calculateBits();
|
||||
prevX = curX1;
|
||||
prevY = curY1;
|
||||
retList.add(ser);
|
||||
} else if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_CURVE_POINT) {
|
||||
CurvedEdgeRecord cer = new CurvedEdgeRecord();
|
||||
cer.controlDeltaX = curX2 - prevX;
|
||||
cer.controlDeltaY = curY2 - prevY;
|
||||
cer.anchorDeltaX = curX1 - curX2;
|
||||
cer.anchorDeltaY = curY1 - curY2;
|
||||
prevX = curX1;
|
||||
prevY = curY1;
|
||||
cer.calculateBits();
|
||||
retList.add(cer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!retList.isEmpty()) {
|
||||
StyleChangeRecord init;
|
||||
if (retList.get(0) instanceof StyleChangeRecord) {
|
||||
init = (StyleChangeRecord) retList.get(0);
|
||||
} else {
|
||||
init = new StyleChangeRecord();
|
||||
retList.add(0, init);
|
||||
}
|
||||
init.stateFillStyle0 = true;
|
||||
init.fillStyle0 = 1;
|
||||
shape.numFillBits = 1;
|
||||
|
||||
} else {
|
||||
shape.numFillBits = 0;
|
||||
|
||||
}
|
||||
retList.add(new EndShapeRecord());
|
||||
shape.shapeRecords = retList;
|
||||
shape.numLineBits = 0;
|
||||
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLE;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.RGB;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShapeToSwfConvertor {
|
||||
|
||||
private static int makeLengthsEmX(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
private static int makeLengthsEmY(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
public static SHAPE convertCharToShape(IggyShape igchar) {
|
||||
SHAPE shape = new SHAPE();
|
||||
List<SHAPERECORD> retList = new ArrayList<>();
|
||||
List<IggyShapeNode> ignodes = igchar.getNodes();
|
||||
|
||||
int prevX = 0;
|
||||
int prevY = 0;
|
||||
|
||||
for (IggyShapeNode ign : ignodes) {
|
||||
if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_MOVE) {
|
||||
StyleChangeRecord scr = new StyleChangeRecord();
|
||||
scr.stateMoveTo = true;
|
||||
prevX = scr.moveDeltaX = makeLengthsEmX(ign.getX1());
|
||||
prevY = scr.moveDeltaY = makeLengthsEmY(ign.getY1());
|
||||
scr.fillStyles = new FILLSTYLEARRAY();
|
||||
scr.lineStyles = new LINESTYLEARRAY();
|
||||
scr.calculateBits();
|
||||
retList.add(scr);
|
||||
} else {
|
||||
|
||||
int curX1 = makeLengthsEmX(ign.getX1());
|
||||
int curY1 = makeLengthsEmY(ign.getY1());
|
||||
|
||||
int curX2 = makeLengthsEmX(ign.getX2());
|
||||
int curY2 = makeLengthsEmY(ign.getY2());
|
||||
|
||||
if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_LINE_TO) {
|
||||
StraightEdgeRecord ser = new StraightEdgeRecord();
|
||||
ser.deltaX = curX1 - prevX;
|
||||
ser.deltaY = curY1 - prevY;
|
||||
ser.generalLineFlag = true;
|
||||
ser.simplify();
|
||||
ser.calculateBits();
|
||||
prevX = curX1;
|
||||
prevY = curY1;
|
||||
retList.add(ser);
|
||||
} else if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_CURVE_POINT) {
|
||||
CurvedEdgeRecord cer = new CurvedEdgeRecord();
|
||||
cer.controlDeltaX = curX2 - prevX;
|
||||
cer.controlDeltaY = curY2 - prevY;
|
||||
cer.anchorDeltaX = curX1 - curX2;
|
||||
cer.anchorDeltaY = curY1 - curY2;
|
||||
prevX = curX1;
|
||||
prevY = curY1;
|
||||
cer.calculateBits();
|
||||
retList.add(cer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!retList.isEmpty()) {
|
||||
StyleChangeRecord init;
|
||||
if (retList.get(0) instanceof StyleChangeRecord) {
|
||||
init = (StyleChangeRecord) retList.get(0);
|
||||
} else {
|
||||
init = new StyleChangeRecord();
|
||||
retList.add(0, init);
|
||||
}
|
||||
init.stateFillStyle0 = true;
|
||||
init.fillStyle0 = 1;
|
||||
shape.numFillBits = 1;
|
||||
|
||||
} else {
|
||||
shape.numFillBits = 0;
|
||||
|
||||
}
|
||||
retList.add(new EndShapeRecord());
|
||||
shape.shapeRecords = retList;
|
||||
shape.numLineBits = 0;
|
||||
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +1,104 @@
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFBundle;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFile;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.helpers.streams.SeekableInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggySwfBundle implements SWFBundle {
|
||||
|
||||
private IggyFile iggyFile;
|
||||
|
||||
public IggySwfBundle(InputStream is) throws IOException {
|
||||
this(is, null);
|
||||
}
|
||||
|
||||
public IggySwfBundle(File filename) throws IOException {
|
||||
this(null, filename);
|
||||
}
|
||||
|
||||
protected IggySwfBundle(InputStream is, File filename) throws IOException {
|
||||
initBundle(is, filename);
|
||||
}
|
||||
|
||||
protected void initBundle(InputStream is, File filename) throws IOException {
|
||||
if (filename == null) {
|
||||
filename = File.createTempFile("bundle", ".iggy");
|
||||
Helper.saveStream(is, filename);
|
||||
}
|
||||
iggyFile = new IggyFile(filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return iggyFile.getSwfCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys() {
|
||||
Set<String> ret = new TreeSet<>();
|
||||
for (int i = 0; i < length(); i++) {
|
||||
ret.add(iggyFile.getSwfName(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int keyToSwfIndex(String key) {
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (key.equals(iggyFile.getSwfName(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Key " + key + " does not exist!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeekableInputStream getSWF(String key) throws IOException {
|
||||
SWF swf = IggyToSwfConvertor.getSwf(iggyFile, keyToSwfIndex(key));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
swf.saveTo(baos);
|
||||
MemoryInputStream mis = new MemoryInputStream(baos.toByteArray());
|
||||
return mis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, SeekableInputStream> getAll() throws IOException {
|
||||
Map<String, SeekableInputStream> ret = new HashMap<>();
|
||||
for (String key : getKeys()) {
|
||||
ret.put(key, getSWF(key));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
return "iggy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return true; //TODO: make writable
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putSWF(String key, InputStream is) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFBundle;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFile;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.MemoryInputStream;
|
||||
import com.jpexs.helpers.ReReadableInputStream;
|
||||
import com.jpexs.helpers.streams.SeekableInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggySwfBundle implements SWFBundle {
|
||||
|
||||
private IggyFile iggyFile;
|
||||
|
||||
public IggySwfBundle(InputStream is) throws IOException {
|
||||
this(is, null);
|
||||
}
|
||||
|
||||
public IggySwfBundle(File filename) throws IOException {
|
||||
this(null, filename);
|
||||
}
|
||||
|
||||
protected IggySwfBundle(InputStream is, File filename) throws IOException {
|
||||
initBundle(is, filename);
|
||||
}
|
||||
|
||||
protected void initBundle(InputStream is, File filename) throws IOException {
|
||||
if (filename == null) {
|
||||
filename = File.createTempFile("bundle", ".iggy");
|
||||
Helper.saveStream(is, filename);
|
||||
}
|
||||
iggyFile = new IggyFile(filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return iggyFile.getSwfCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys() {
|
||||
Set<String> ret = new TreeSet<>();
|
||||
for (int i = 0; i < length(); i++) {
|
||||
ret.add(iggyFile.getSwfName(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int keyToSwfIndex(String key) {
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (key.equals(iggyFile.getSwfName(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Key " + key + " does not exist!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeekableInputStream getSWF(String key) throws IOException {
|
||||
SWF swf = IggyToSwfConvertor.getSwf(iggyFile, keyToSwfIndex(key));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
swf.saveTo(baos);
|
||||
MemoryInputStream mis = new MemoryInputStream(baos.toByteArray());
|
||||
return mis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, SeekableInputStream> getAll() throws IOException {
|
||||
Map<String, SeekableInputStream> ret = new HashMap<>();
|
||||
for (String key : getKeys()) {
|
||||
ret.put(key, getSWF(key));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
return "iggy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return true; //TODO: make writable
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putSWF(String key, InputStream is) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,320 +1,248 @@
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFCompression;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFile;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFont;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyText;
|
||||
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.EndTag;
|
||||
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* WIP
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyToSwfConvertor {
|
||||
|
||||
public static SWF[] getAllSwfs(IggyFile file) {
|
||||
SWF[] ret = new SWF[file.getSwfCount()];
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = getSwf(file, i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
|
||||
for (int swfIndex = 0; swfIndex < file.getSwfCount(); swfIndex++) {
|
||||
exportSwfToDir(file, swfIndex, outputDir);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwfToDir(IggyFile file, int swfIndex, File outputDir) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName(swfIndex)))) {
|
||||
exportSwf(file, swfIndex, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwfToFile(IggyFile file, int swfIndex, File outputFile) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
|
||||
exportSwf(file, swfIndex, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwf(IggyFile file, int swfIndex, OutputStream output) throws IOException {
|
||||
SWF swf = getSwf(file, swfIndex);
|
||||
swf.saveTo(output);
|
||||
}
|
||||
|
||||
private static int makeLengthsTwip(double val) {
|
||||
return (int) (val * SWF.unitDivisor);
|
||||
}
|
||||
|
||||
private static int makeLengthsEm(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
private static SHAPE createEmptyChar() {
|
||||
SHAPE shape = new SHAPE();
|
||||
List<SHAPERECORD> retList = new ArrayList<>();
|
||||
|
||||
{
|
||||
StyleChangeRecord scr = new StyleChangeRecord();
|
||||
scr.stateMoveTo = true;
|
||||
scr.moveDeltaX = 0;
|
||||
scr.moveDeltaY = 0;
|
||||
scr.fillStyles = new FILLSTYLEARRAY();
|
||||
scr.lineStyles = new LINESTYLEARRAY();
|
||||
scr.calculateBits();
|
||||
retList.add(scr);
|
||||
}
|
||||
|
||||
/*{
|
||||
StraightEdgeRecord ser = new StraightEdgeRecord();
|
||||
ser.deltaX = 1024;
|
||||
ser.deltaY = 0;
|
||||
ser.generalLineFlag = true;
|
||||
ser.simplify();
|
||||
ser.calculateBits();
|
||||
retList.add(ser);
|
||||
}
|
||||
|
||||
{
|
||||
StraightEdgeRecord ser = new StraightEdgeRecord();
|
||||
ser.deltaX = 0;
|
||||
ser.deltaY = -1024;
|
||||
ser.generalLineFlag = true;
|
||||
ser.simplify();
|
||||
ser.calculateBits();
|
||||
retList.add(ser);
|
||||
}
|
||||
|
||||
{
|
||||
StraightEdgeRecord ser = new StraightEdgeRecord();
|
||||
ser.deltaX = -1024;
|
||||
ser.deltaY = 0;
|
||||
ser.generalLineFlag = true;
|
||||
ser.simplify();
|
||||
ser.calculateBits();
|
||||
retList.add(ser);
|
||||
}
|
||||
|
||||
{
|
||||
StraightEdgeRecord ser = new StraightEdgeRecord();
|
||||
ser.deltaX = 0;
|
||||
ser.deltaY = 1024;
|
||||
ser.generalLineFlag = true;
|
||||
ser.simplify();
|
||||
ser.calculateBits();
|
||||
retList.add(ser);
|
||||
}*/
|
||||
StyleChangeRecord init;
|
||||
if (!retList.isEmpty() && retList.get(0) instanceof StyleChangeRecord) {
|
||||
init = (StyleChangeRecord) retList.get(0);
|
||||
} else {
|
||||
init = new StyleChangeRecord();
|
||||
retList.add(0, init);
|
||||
}
|
||||
|
||||
retList.add(new EndShapeRecord());
|
||||
init.stateFillStyle1 = true;
|
||||
init.fillStyle1 = 1;
|
||||
shape.shapeRecords = retList;
|
||||
shape.numFillBits = 1;
|
||||
shape.numLineBits = 0;
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
public static SWF getSwf(IggyFile file, int swfIndex) {
|
||||
SWF swf = new SWF();
|
||||
swf.compression = SWFCompression.NONE;
|
||||
swf.frameCount = 1; //FIXME!!
|
||||
swf.frameRate = file.getSwfFrameRate(swfIndex);
|
||||
swf.gfx = false;
|
||||
swf.displayRect = new RECT(
|
||||
(int) (file.getSwfXMin(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfXMax(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMin(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMax(swfIndex) * SWF.unitDivisor));
|
||||
swf.version = 10; //FIXME
|
||||
|
||||
FileAttributesTag fat = new FileAttributesTag(swf);
|
||||
fat.actionScript3 = false;
|
||||
fat.hasMetadata = false;
|
||||
fat.useNetwork = false;
|
||||
swf.addTag(fat);
|
||||
|
||||
Set<Integer> fontIndices = file.getFontIds(swfIndex);
|
||||
|
||||
int currentCharId = 0;
|
||||
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
|
||||
|
||||
for (int fontIndex : fontIndices) {
|
||||
IggyFont iggyFont = file.getFont(swfIndex, fontIndex);
|
||||
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
|
||||
currentCharId++;
|
||||
fontIndex2CharId.put(fontIndex, currentCharId);
|
||||
fontTag.fontID = currentCharId;
|
||||
/*System.out.println("===================");
|
||||
System.out.println("xscale: " + iggyFont.getXscale()); //80
|
||||
System.out.println("yscale: " + iggyFont.getYscale()); //19
|
||||
|
||||
System.out.println("unk_float1: " + iggyFont.getUnk_float()[0]);
|
||||
System.out.println("unk_float2: " + iggyFont.getUnk_float()[1]);
|
||||
System.out.println("unk_float3: " + iggyFont.getUnk_float()[2]);
|
||||
System.out.println("unk_float4: " + iggyFont.getUnk_float()[3]);
|
||||
System.out.println("unk_float5: " + iggyFont.getUnk_float()[4]);
|
||||
System.out.println("what_2: " + iggyFont.getWhat_2());
|
||||
System.out.println("what_3: " + iggyFont.getWhat_3());*/
|
||||
|
||||
fontTag.fontKerningTable = new ArrayList<>();
|
||||
IggyCharKerning ker = iggyFont.getCharKernings();
|
||||
if (ker != null) {
|
||||
for (int i = 0; i < ker.getKernCount(); i++) {
|
||||
int kerningCode1 = ker.getCharsA().get(i);
|
||||
int kerningCode2 = ker.getCharsA().get(i);
|
||||
int kerningOffset = ker.getKerningOffsets().get(i);
|
||||
fontTag.fontKerningTable.add(new KERNINGRECORD(kerningCode1, kerningCode2, kerningOffset));
|
||||
}
|
||||
}
|
||||
|
||||
fontTag.fontFlagsWideCodes = true;
|
||||
fontTag.fontFlagsWideOffsets = true;
|
||||
fontTag.fontAscent = iggyFont.getAscent();
|
||||
fontTag.fontDescent = iggyFont.getDescent();
|
||||
fontTag.fontLeading = iggyFont.getLeading();
|
||||
fontTag.codeTable = new ArrayList<>();
|
||||
fontTag.fontName = iggyFont.getName();
|
||||
fontTag.glyphShapeTable = new ArrayList<>();
|
||||
fontTag.fontBoundsTable = new ArrayList<>();
|
||||
fontTag.fontAdvanceTable = new ArrayList<>();
|
||||
fontTag.fontFlagsHasLayout = true;
|
||||
IggyCharAdvances advanceValues = iggyFont.getCharAdvances();
|
||||
for (int i = 0; i < iggyFont.getCharacterCount(); i++) {
|
||||
int code = iggyFont.getCharIndices().getChars().get(i);
|
||||
IggyShape glyph = iggyFont.getChars().get(i);
|
||||
fontTag.codeTable.add(code);
|
||||
SHAPE shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
|
||||
fontTag.glyphShapeTable.add(shp);
|
||||
fontTag.fontBoundsTable.add(shp.getBounds());
|
||||
fontTag.fontAdvanceTable.add(makeLengthsEm(advanceValues.getScales().get(i)));
|
||||
|
||||
}
|
||||
fontTag.setModified(true);
|
||||
swf.addTag(fontTag);
|
||||
}
|
||||
|
||||
/*
|
||||
//TODO: Texts, they are incomplete
|
||||
|
||||
Map<Integer, Integer> textIndex2CharId = new HashMap<>();
|
||||
|
||||
Set<Integer> textIds = file.getTextIds(swfIndex);
|
||||
for (int textId : textIds) {
|
||||
IggyText iggyText = file.getText(swfIndex, textId);
|
||||
DefineEditTextTag textTag = new DefineEditTextTag(swf);
|
||||
currentCharId++;
|
||||
textIndex2CharId.put(iggyText.getTextIndex(), currentCharId);
|
||||
textTag.characterID = currentCharId;
|
||||
textTag.hasText = true;
|
||||
textTag.initialText = iggyText.getInitialText();
|
||||
textTag.html = true;
|
||||
textTag.noSelect = true;
|
||||
textTag.wasStatic = true;
|
||||
textTag.hasFont = false;
|
||||
textTag.hasFontClass = false;
|
||||
textTag.hasMaxLength = false;
|
||||
//textTag.multiline = true;
|
||||
//textTag.wordWrap = true;
|
||||
//textTag.hasTextColor = true;
|
||||
//textTag.textColor = new RGBA(Color.black);
|
||||
//textTag.fontHeight = 40; //??
|
||||
textTag.readOnly = true;
|
||||
textTag.bounds = new RECT(
|
||||
makeLengthsTwip(iggyText.getPar3()),
|
||||
makeLengthsTwip(iggyText.getPar1()),
|
||||
makeLengthsTwip(iggyText.getPar4()),
|
||||
makeLengthsTwip(iggyText.getPar2())
|
||||
);
|
||||
|
||||
//textTag.hasFont = true;
|
||||
//textTag.fontId = fontIndex2CharId.get(iggyText.getFontIndex());
|
||||
textTag.setModified(true);
|
||||
swf.addTag(textTag);
|
||||
}
|
||||
*/
|
||||
swf.addTag(
|
||||
new EndTag(swf));
|
||||
swf.setModified(
|
||||
true);
|
||||
|
||||
return swf;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
if (args.length < 2 || (args[0].isEmpty() || args[1].isEmpty())) {
|
||||
System.err.println("Invalid arguments");
|
||||
System.err.println("Usage: iggy-extract.bat file.iggy d:/outdir/");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File file = new File(args[0]);
|
||||
if (!file.exists()) {
|
||||
System.err.println("FAIL: Input file: " + file.getAbsolutePath() + " does not exist.");
|
||||
System.exit(1);
|
||||
}
|
||||
File outDir = new File(args[1]);
|
||||
if (!outDir.exists()) {
|
||||
if (!outDir.mkdirs()) {
|
||||
System.err.println("FAIL: Cannot create output directory");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
System.out.print("(1/2) Loading file " + args[0] + "...");
|
||||
IggyFile iggyFile = new IggyFile(new File(args[0]));
|
||||
System.out.println("OK");
|
||||
System.out.print("(2/2) Exporting SWF files to " + args[1] + "...");
|
||||
exportAllSwfsToDir(iggyFile, new File(args[1]));
|
||||
System.out.println("OK");
|
||||
System.out.println("All finished sucessfully.");
|
||||
System.exit(0);
|
||||
} catch (IOException ex) {
|
||||
System.out.println("FAIL");
|
||||
System.err.println("Error while converting: " + ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFCompression;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFile;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFont;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyText;
|
||||
import com.jpexs.decompiler.flash.tags.DefineEditTextTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.EndTag;
|
||||
import com.jpexs.decompiler.flash.tags.FileAttributesTag;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import java.awt.Color;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* WIP
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyToSwfConvertor {
|
||||
|
||||
public static SWF[] getAllSwfs(IggyFile file) {
|
||||
SWF[] ret = new SWF[file.getSwfCount()];
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = getSwf(file, i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
|
||||
for (int swfIndex = 0; swfIndex < file.getSwfCount(); swfIndex++) {
|
||||
exportSwfToDir(file, swfIndex, outputDir);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwfToDir(IggyFile file, int swfIndex, File outputDir) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName(swfIndex)))) {
|
||||
exportSwf(file, swfIndex, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwfToFile(IggyFile file, int swfIndex, File outputFile) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
|
||||
exportSwf(file, swfIndex, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwf(IggyFile file, int swfIndex, OutputStream output) throws IOException {
|
||||
SWF swf = getSwf(file, swfIndex);
|
||||
swf.saveTo(output);
|
||||
}
|
||||
|
||||
private static int makeLengthsTwip(double val) {
|
||||
return (int) (val * SWF.unitDivisor);
|
||||
}
|
||||
|
||||
private static int makeLengthsEm(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
public static SWF getSwf(IggyFile file, int swfIndex) {
|
||||
SWF swf = new SWF();
|
||||
swf.compression = SWFCompression.NONE;
|
||||
swf.frameCount = 1; //FIXME!!
|
||||
swf.frameRate = file.getSwfFrameRate(swfIndex);
|
||||
swf.gfx = false;
|
||||
swf.displayRect = new RECT(
|
||||
(int) (file.getSwfXMin(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfXMax(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMin(swfIndex) * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMax(swfIndex) * SWF.unitDivisor));
|
||||
swf.version = 10; //FIXME
|
||||
|
||||
FileAttributesTag fat = new FileAttributesTag(swf);
|
||||
fat.actionScript3 = false;
|
||||
fat.hasMetadata = false;
|
||||
fat.useNetwork = false;
|
||||
swf.addTag(fat);
|
||||
|
||||
Set<Integer> fontIndices = file.getFontIds(swfIndex);
|
||||
|
||||
int currentCharId = 0;
|
||||
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
|
||||
|
||||
for (int fontIndex : fontIndices) {
|
||||
IggyFont iggyFont = file.getFont(swfIndex, fontIndex);
|
||||
DefineFont2Tag fontTag = new DefineFont2Tag(swf);
|
||||
currentCharId++;
|
||||
fontIndex2CharId.put(fontIndex, currentCharId);
|
||||
fontTag.fontID = currentCharId;
|
||||
/*System.out.println("===================");
|
||||
System.out.println("xscale: " + iggyFont.getXscale()); //80
|
||||
System.out.println("yscale: " + iggyFont.getYscale()); //19
|
||||
|
||||
System.out.println("unk_float1: " + iggyFont.getUnk_float()[0]);
|
||||
System.out.println("unk_float2: " + iggyFont.getUnk_float()[1]);
|
||||
System.out.println("unk_float3: " + iggyFont.getUnk_float()[2]);
|
||||
System.out.println("unk_float4: " + iggyFont.getUnk_float()[3]);
|
||||
System.out.println("unk_float5: " + iggyFont.getUnk_float()[4]);
|
||||
System.out.println("what_2: " + iggyFont.getWhat_2());
|
||||
System.out.println("what_3: " + iggyFont.getWhat_3());*/
|
||||
|
||||
fontTag.fontKerningTable = new ArrayList<>();
|
||||
IggyCharKerning ker = iggyFont.getCharKernings();
|
||||
if (ker != null) {
|
||||
for (int i = 0; i < ker.getKernCount(); i++) {
|
||||
int kerningCode1 = ker.getCharsA().get(i);
|
||||
int kerningCode2 = ker.getCharsA().get(i);
|
||||
int kerningOffset = makeLengthsEm(ker.getKerningOffsets().get(i));
|
||||
fontTag.fontKerningTable.add(new KERNINGRECORD(kerningCode1, kerningCode2, kerningOffset));
|
||||
}
|
||||
}
|
||||
|
||||
fontTag.fontFlagsWideCodes = true;
|
||||
fontTag.fontFlagsWideOffsets = true;
|
||||
fontTag.fontAscent = iggyFont.getAscent();
|
||||
fontTag.fontDescent = iggyFont.getDescent();
|
||||
fontTag.fontLeading = iggyFont.getLeading();
|
||||
fontTag.codeTable = new ArrayList<>();
|
||||
fontTag.fontName = iggyFont.getName();
|
||||
fontTag.glyphShapeTable = new ArrayList<>();
|
||||
fontTag.fontBoundsTable = new ArrayList<>();
|
||||
fontTag.fontAdvanceTable = new ArrayList<>();
|
||||
fontTag.fontFlagsHasLayout = true;
|
||||
IggyCharAdvances advanceValues = iggyFont.getCharAdvances();
|
||||
for (int i = 0; i < iggyFont.getCharacterCount(); i++) {
|
||||
int code = iggyFont.getCharIndices().getChars().get(i);
|
||||
IggyShape glyph = iggyFont.getChars().get(i);
|
||||
fontTag.codeTable.add(code);
|
||||
SHAPE shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
|
||||
fontTag.glyphShapeTable.add(shp);
|
||||
fontTag.fontBoundsTable.add(shp.getBounds());
|
||||
fontTag.fontAdvanceTable.add(makeLengthsEm(advanceValues.getScales().get(i)));
|
||||
|
||||
}
|
||||
fontTag.setModified(true);
|
||||
swf.addTag(fontTag);
|
||||
}
|
||||
|
||||
/*
|
||||
//TODO: Texts, they are incomplete
|
||||
|
||||
Map<Integer, Integer> textIndex2CharId = new HashMap<>();
|
||||
|
||||
Set<Integer> textIds = file.getTextIds(swfIndex);
|
||||
for (int textId : textIds) {
|
||||
IggyText iggyText = file.getText(swfIndex, textId);
|
||||
DefineEditTextTag textTag = new DefineEditTextTag(swf);
|
||||
currentCharId++;
|
||||
textIndex2CharId.put(iggyText.getTextIndex(), currentCharId);
|
||||
textTag.characterID = currentCharId;
|
||||
textTag.hasText = true;
|
||||
textTag.initialText = iggyText.getInitialText();
|
||||
textTag.html = true;
|
||||
textTag.noSelect = true;
|
||||
textTag.wasStatic = true;
|
||||
textTag.hasFont = false;
|
||||
textTag.hasFontClass = false;
|
||||
textTag.hasMaxLength = false;
|
||||
//textTag.multiline = true;
|
||||
//textTag.wordWrap = true;
|
||||
//textTag.hasTextColor = true;
|
||||
//textTag.textColor = new RGBA(Color.black);
|
||||
//textTag.fontHeight = 40; //??
|
||||
textTag.readOnly = true;
|
||||
textTag.bounds = new RECT(
|
||||
makeLengthsTwip(iggyText.getPar3()),
|
||||
makeLengthsTwip(iggyText.getPar1()),
|
||||
makeLengthsTwip(iggyText.getPar4()),
|
||||
makeLengthsTwip(iggyText.getPar2())
|
||||
);
|
||||
|
||||
//textTag.hasFont = true;
|
||||
//textTag.fontId = fontIndex2CharId.get(iggyText.getFontIndex());
|
||||
textTag.setModified(true);
|
||||
swf.addTag(textTag);
|
||||
}
|
||||
*/
|
||||
swf.addTag(
|
||||
new EndTag(swf));
|
||||
swf.setModified(
|
||||
true);
|
||||
|
||||
return swf;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
if (args.length < 2 || (args[0].isEmpty() || args[1].isEmpty())) {
|
||||
System.err.println("Invalid arguments");
|
||||
System.err.println("Usage: iggy-extract.bat file.iggy d:/outdir/");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File file = new File(args[0]);
|
||||
if (!file.exists()) {
|
||||
System.err.println("FAIL: Input file: " + file.getAbsolutePath() + " does not exist.");
|
||||
System.exit(1);
|
||||
}
|
||||
File outDir = new File(args[1]);
|
||||
if (!outDir.exists()) {
|
||||
if (!outDir.mkdirs()) {
|
||||
System.err.println("FAIL: Cannot create output directory");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
System.out.print("(1/2) Loading file " + args[0] + "...");
|
||||
IggyFile iggyFile = new IggyFile(new File(args[0]));
|
||||
System.out.println("OK");
|
||||
System.out.print("(2/2) Exporting SWF files to " + args[1] + "...");
|
||||
exportAllSwfsToDir(iggyFile, new File(args[1]));
|
||||
System.out.println("OK");
|
||||
System.out.println("All finished sucessfully.");
|
||||
System.exit(0);
|
||||
} catch (IOException ex) {
|
||||
System.out.println("FAIL");
|
||||
System.err.println("Error while converting: " + ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user