Saving files before refreshing line endings

This commit is contained in:
Jindra Petřík
2016-11-27 06:56:24 +01:00
parent c885eb506c
commit ce4719fe35
39 changed files with 19019 additions and 19091 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
}

View File

@@ -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
}
}

View File

@@ -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);
}
}

View File

@@ -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
}

View File

@@ -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.");
}
}

View File

@@ -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.");
}
}

View File

@@ -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.
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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.");
}
}

View File

@@ -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;
}
}

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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.");
}
}

View File

@@ -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);
}
}
}