mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-31 02:55:10 +00:00
Saving files before refreshing line endings
This commit is contained in:
@@ -1,39 +1,39 @@
|
||||
/*
|
||||
* 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.dumpview;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DumpInfoSpecial extends DumpInfo {
|
||||
|
||||
public DumpInfoSpecialType specialType;
|
||||
|
||||
public Object specialValue;
|
||||
|
||||
public DumpInfoSpecial(String name, String type, Object value, long startByte, int startBit, long lengthBytes, int lengthBits, DumpInfoSpecialType specialType) {
|
||||
super(name, type, value, startByte, startBit, lengthBytes, lengthBits);
|
||||
this.specialType = specialType;
|
||||
}
|
||||
|
||||
public DumpInfoSpecial(String name, String type, Object value, long startByte, int startBit, long lengthBytes, int lengthBits, DumpInfoSpecialType specialType, Object specialValue) {
|
||||
super(name, type, value, startByte, startBit, lengthBytes, lengthBits);
|
||||
this.specialType = specialType;
|
||||
this.specialValue = specialValue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.dumpview;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DumpInfoSpecial extends DumpInfo {
|
||||
|
||||
public DumpInfoSpecialType specialType;
|
||||
|
||||
public Object specialValue;
|
||||
|
||||
public DumpInfoSpecial(String name, String type, Object value, long startByte, int startBit, long lengthBytes, int lengthBits, DumpInfoSpecialType specialType) {
|
||||
super(name, type, value, startByte, startBit, lengthBytes, lengthBits);
|
||||
this.specialType = specialType;
|
||||
}
|
||||
|
||||
public DumpInfoSpecial(String name, String type, Object value, long startByte, int startBit, long lengthBytes, int lengthBits, DumpInfoSpecialType specialType, Object specialValue) {
|
||||
super(name, type, value, startByte, startBit, lengthBytes, lengthBits);
|
||||
this.specialType = specialType;
|
||||
this.specialValue = specialValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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, int64_t,
|
||||
wchar_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, int64_t,
|
||||
wchar_t //or maybe just "string"? It has two bytes per character and is null terminated
|
||||
}
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
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(List<Float> advances) {
|
||||
this.advances = advances;
|
||||
this.charCount = advances.size();
|
||||
}
|
||||
|
||||
public IggyCharAdvances(ReadDataStreamInterface stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
advances = new ArrayList<>();
|
||||
for (int i = 0; i < charCount; i++) {
|
||||
advances.add(stream.readFloat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
for (int i = 0; i < advances.size(); i++) {
|
||||
stream.writeFloat(advances.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
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(List<Float> advances) {
|
||||
this.advances = advances;
|
||||
this.charCount = advances.size();
|
||||
}
|
||||
|
||||
public IggyCharAdvances(ReadDataStreamInterface stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
advances = new ArrayList<>();
|
||||
for (int i = 0; i < charCount; i++) {
|
||||
advances.add(stream.readFloat());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
for (int i = 0; i < advances.size(); i++) {
|
||||
stream.writeFloat(advances.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharIndices implements StructureInterface {
|
||||
|
||||
@IggyFieldType(value = DataType.wchar_t)
|
||||
List<Character> chars;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long padd;
|
||||
|
||||
public List<Character> getChars() {
|
||||
return chars;
|
||||
}
|
||||
|
||||
private long charCount;
|
||||
|
||||
public IggyCharIndices(List<Character> chars) {
|
||||
this.chars = chars;
|
||||
this.charCount = chars.size();
|
||||
padd = 0;
|
||||
}
|
||||
|
||||
public IggyCharIndices(ReadDataStreamInterface stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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(WriteDataStreamInterface stream) throws IOException {
|
||||
for (int i = 0; i < chars.size(); i++) {
|
||||
stream.writeUI16(chars.get(i));
|
||||
}
|
||||
stream.writeUI32(padd);
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharIndices implements StructureInterface {
|
||||
|
||||
@IggyFieldType(value = DataType.wchar_t)
|
||||
List<Character> chars;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long padd;
|
||||
|
||||
public List<Character> getChars() {
|
||||
return chars;
|
||||
}
|
||||
|
||||
private long charCount;
|
||||
|
||||
public IggyCharIndices(List<Character> chars) {
|
||||
this.chars = chars;
|
||||
this.charCount = chars.size();
|
||||
padd = 0;
|
||||
}
|
||||
|
||||
public IggyCharIndices(ReadDataStreamInterface stream, long charCount) throws IOException {
|
||||
this.charCount = charCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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(WriteDataStreamInterface stream) throws IOException {
|
||||
for (int i = 0; i < chars.size(); i++) {
|
||||
stream.writeUI16(chars.get(i));
|
||||
}
|
||||
stream.writeUI32(padd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharKerning implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 6;
|
||||
|
||||
private long kernCount;
|
||||
List<Character> charsA;
|
||||
List<Character> charsB;
|
||||
List<Short> kerningOffsets;
|
||||
|
||||
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(List<Character> charsA, List<Character> charsB, List<Short> kerningOffsets) {
|
||||
if ((charsA.size() != charsB.size()) || (charsB.size() != kerningOffsets.size())) {
|
||||
throw new RuntimeException("sizes of charsA, charsB and offsets must match");
|
||||
}
|
||||
this.kernCount = charsA.size();
|
||||
this.charsA = charsA;
|
||||
this.charsB = charsB;
|
||||
this.kerningOffsets = kerningOffsets;
|
||||
}
|
||||
|
||||
public IggyCharKerning(ReadDataStreamInterface stream, long kernCount) throws IOException {
|
||||
this.kernCount = kernCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
for (int i = 0; i < kernCount; i++) {
|
||||
stream.writeUI16(charsA.get(i));
|
||||
stream.writeUI16(charsB.get(i));
|
||||
stream.writeUI16(kerningOffsets.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharKerning implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 6;
|
||||
|
||||
private long kernCount;
|
||||
List<Character> charsA;
|
||||
List<Character> charsB;
|
||||
List<Short> kerningOffsets;
|
||||
|
||||
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(List<Character> charsA, List<Character> charsB, List<Short> kerningOffsets) {
|
||||
if ((charsA.size() != charsB.size()) || (charsB.size() != kerningOffsets.size())) {
|
||||
throw new RuntimeException("sizes of charsA, charsB and offsets must match");
|
||||
}
|
||||
this.kernCount = charsA.size();
|
||||
this.charsA = charsA;
|
||||
this.charsB = charsB;
|
||||
this.kerningOffsets = kerningOffsets;
|
||||
}
|
||||
|
||||
public IggyCharKerning(ReadDataStreamInterface stream, long kernCount) throws IOException {
|
||||
this.kernCount = kernCount;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
for (int i = 0; i < kernCount; i++) {
|
||||
stream.writeUI16(charsA.get(i));
|
||||
stream.writeUI16(charsB.get(i));
|
||||
stream.writeUI16(kerningOffsets.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,108 +1,108 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharOffset implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 32;
|
||||
|
||||
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(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyCharOffset(int ischar1, int ischar2, int xscale, int yscale) {
|
||||
this.zero = 0;
|
||||
this.ischar1 = ischar1;
|
||||
this.ischar2 = ischar2;
|
||||
this.zero2 = 0;
|
||||
this.xscale = xscale;
|
||||
this.yscale = yscale;
|
||||
this.zero3 = 0;
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
zero = stream.readUI64();
|
||||
ischar1 = stream.readUI16();
|
||||
ischar2 = stream.readUI16();
|
||||
zero2 = stream.readUI32();
|
||||
xscale = stream.readUI16();
|
||||
yscale = stream.readUI16();
|
||||
zero3 = stream.readUI32();
|
||||
offset = stream.readUI64();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
stream.writeUI64(zero);
|
||||
stream.writeUI16(ischar1);
|
||||
stream.writeUI16(ischar2);
|
||||
stream.writeUI32(zero2);
|
||||
stream.writeUI16(xscale);
|
||||
stream.writeUI16(yscale);
|
||||
stream.writeUI32(zero3);
|
||||
stream.writeUI64(offset);
|
||||
}
|
||||
|
||||
public boolean hasGlyph() {
|
||||
return offset > 0;
|
||||
}
|
||||
|
||||
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 com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyCharOffset implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 32;
|
||||
|
||||
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(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyCharOffset(int ischar1, int ischar2, int xscale, int yscale) {
|
||||
this.zero = 0;
|
||||
this.ischar1 = ischar1;
|
||||
this.ischar2 = ischar2;
|
||||
this.zero2 = 0;
|
||||
this.xscale = xscale;
|
||||
this.yscale = yscale;
|
||||
this.zero3 = 0;
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
zero = stream.readUI64();
|
||||
ischar1 = stream.readUI16();
|
||||
ischar2 = stream.readUI16();
|
||||
zero2 = stream.readUI32();
|
||||
xscale = stream.readUI16();
|
||||
yscale = stream.readUI16();
|
||||
zero3 = stream.readUI32();
|
||||
offset = stream.readUI64();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
stream.writeUI64(zero);
|
||||
stream.writeUI16(ischar1);
|
||||
stream.writeUI16(ischar2);
|
||||
stream.writeUI32(zero2);
|
||||
stream.writeUI16(xscale);
|
||||
stream.writeUI16(yscale);
|
||||
stream.writeUI32(zero3);
|
||||
stream.writeUI64(offset);
|
||||
}
|
||||
|
||||
public boolean hasGlyph() {
|
||||
return offset > 0;
|
||||
}
|
||||
|
||||
public long getZero() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
public boolean isChar1() {
|
||||
return ischar1 > 0;
|
||||
}
|
||||
|
||||
public boolean isChar2() {
|
||||
return ischar2 > 0;
|
||||
}
|
||||
|
||||
public long getZero2() {
|
||||
return zero2;
|
||||
}
|
||||
|
||||
public int getXscale() {
|
||||
return xscale;
|
||||
}
|
||||
|
||||
public int getYscale() {
|
||||
return yscale;
|
||||
}
|
||||
|
||||
public long getZero3() {
|
||||
return zero3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyDeclStrings implements StructureInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long size;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 3)
|
||||
byte xxx[];
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, countField = "size")
|
||||
byte data[];
|
||||
byte padd[];
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one2;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero;
|
||||
|
||||
public IggyDeclStrings(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
one = s.readUI64();
|
||||
size = s.readUI32();
|
||||
xxx = s.readBytes(3);
|
||||
data = s.readBytes((int) size);
|
||||
if ((15 + size) % 8 != 0) {
|
||||
padd = s.readBytes((int) (((15 + size) / 8 + 1) * 8 - 15 - size));
|
||||
} else {
|
||||
padd = new byte[0];
|
||||
}
|
||||
one = s.readUI64();
|
||||
if (one != 1) {
|
||||
throw new IOException("Wrong iggy font format (declend)!");
|
||||
}
|
||||
zero = s.readUI64();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
IggyIndexBuilder ib = s.getIndexing();
|
||||
s.writeUI64(one);
|
||||
s.writeUI32(size);
|
||||
s.writeBytes(xxx);
|
||||
ib.writeLengthCustom(15, new int[]{0x00, 0x08}, new int[]{2, 5});
|
||||
ib.writeLengthUI32(size);
|
||||
s.writeBytes(data);
|
||||
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
|
||||
s.writeBytes(padd);
|
||||
s.writeUI64(one);
|
||||
s.writeUI64(zero);
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyDeclStrings implements StructureInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long size;
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, count = 3)
|
||||
byte xxx[];
|
||||
@IggyArrayFieldType(value = DataType.uint8_t, countField = "size")
|
||||
byte data[];
|
||||
byte padd[];
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long one2;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero;
|
||||
|
||||
public IggyDeclStrings(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
one = s.readUI64();
|
||||
size = s.readUI32();
|
||||
xxx = s.readBytes(3);
|
||||
data = s.readBytes((int) size);
|
||||
if ((15 + size) % 8 != 0) {
|
||||
padd = s.readBytes((int) (((15 + size) / 8 + 1) * 8 - 15 - size));
|
||||
} else {
|
||||
padd = new byte[0];
|
||||
}
|
||||
one = s.readUI64();
|
||||
if (one != 1) {
|
||||
throw new IOException("Wrong iggy font format (declend)!");
|
||||
}
|
||||
zero = s.readUI64();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
IggyIndexBuilder ib = s.getIndexing();
|
||||
s.writeUI64(one);
|
||||
s.writeUI32(size);
|
||||
s.writeBytes(xxx);
|
||||
ib.writeLengthCustom(15, new int[]{0x00, 0x08}, new int[]{2, 5});
|
||||
ib.writeLengthUI32(size);
|
||||
s.writeBytes(data);
|
||||
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
|
||||
s.writeBytes(padd);
|
||||
s.writeUI64(one);
|
||||
s.writeUI64(zero);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,197 +1,197 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
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(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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(WriteDataStreamInterface 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 com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
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(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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(WriteDataStreamInterface stream) throws IOException {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("[\r\n");
|
||||
sb.append("main_offset ").append(main_offset).append("\r\n");
|
||||
sb.append("as3_section_offset ").append(as3_section_offset).append("\r\n");
|
||||
sb.append("unk_offset ").append(unk_offset).append("\r\n");
|
||||
sb.append("unk_offset2 ").append(unk_offset2).append("\r\n");
|
||||
sb.append("unk_offset3 ").append(unk_offset3).append("\r\n");
|
||||
sb.append("unk_offset4 ").append(unk_offset4).append("\r\n");
|
||||
sb.append("xmin ").append(xmin).append("\r\n");
|
||||
sb.append("ymin ").append(ymin).append("\r\n");
|
||||
sb.append("xmax ").append(xmax).append("\r\n");
|
||||
sb.append("ymax ").append(ymax).append("\r\n");
|
||||
sb.append("unk_28 ").append(unk_28).append("\r\n");
|
||||
sb.append("unk_2C ").append(unk_2C).append("\r\n");
|
||||
sb.append("unk_30 ").append(unk_30).append("\r\n");
|
||||
sb.append("unk_34 ").append(unk_34).append("\r\n");
|
||||
sb.append("unk_38 ").append(unk_38).append("\r\n");
|
||||
sb.append("unk_3C ").append(unk_3C).append("\r\n");
|
||||
sb.append("frameRate ").append(frameRate).append("\r\n");
|
||||
sb.append("unk_44 ").append(unk_44).append("\r\n");
|
||||
sb.append("unk_48 ").append(unk_48).append("\r\n");
|
||||
sb.append("unk_4C ").append(unk_4C).append("\r\n");
|
||||
sb.append("names_offset ").append(names_offset).append("\r\n");
|
||||
sb.append("unk_offset5 ").append(unk_offset5).append("\r\n");
|
||||
sb.append("unk_58 ").append(unk_58).append("\r\n");
|
||||
sb.append("last_section_offset ").append(last_section_offset).append("\r\n");
|
||||
sb.append("unk_offset6 ").append(unk_offset6).append("\r\n");
|
||||
sb.append("as3_code_offset ").append(as3_code_offset).append("\r\n");
|
||||
sb.append("as3_names_offset ").append(as3_names_offset).append("\r\n");
|
||||
sb.append("unk_70 ").append(unk_70).append("\r\n");
|
||||
sb.append("unk_74 ").append(unk_74).append("\r\n");
|
||||
sb.append("unk_78 ").append(unk_78).append("\r\n");
|
||||
sb.append("unk_7C ").append(unk_7C).append("\r\n");
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frameRate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,393 +1,393 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.FieldPrinter;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_base; // 0 Relative offset to first section (matches sizeof header);
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_end; // 8 Relative offset to as3 file names table...
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_font_end; // 0x10 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_start1; // 0x18 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_start2; // 0x20 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_start3; // 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 imported_guid;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long my_guid; // same for some fonts (eng + chinese)
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_names; // 0x70 relative offset to the names/import section of the file - end of fonts
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_unk78; // 0x78 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk80;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_last_section;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_flash_filename;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_decl_strings;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_type_of_fonts;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long flags;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long font_count;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero2;
|
||||
|
||||
// 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(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
private long base_address;
|
||||
private long sequence_end_address;
|
||||
private long font_end_address;
|
||||
private long sequence_start_address1;
|
||||
private long sequence_start_address2;
|
||||
private long sequence_start_address3;
|
||||
private long names_address;
|
||||
private long unk78_address;
|
||||
private long last_section_address;
|
||||
private long flash_filename_address;
|
||||
private long decl_strings_address;
|
||||
private long type_fonts_address;
|
||||
|
||||
private long base_ofs_pos;
|
||||
private long sequence_end_ofs_pos;
|
||||
private long font_end_ofs_pos;
|
||||
private long sequence_start1_ofs_pos;
|
||||
private long sequence_start2_ofs_pos;
|
||||
private long sequence_start3_ofs_pos;
|
||||
private long names_ofs_pos;
|
||||
private long unk78_ofs_pos;
|
||||
private long last_section_ofs_pos;
|
||||
private long flash_filename_ofs_pos;
|
||||
private long decl_strings_ofs_pos;
|
||||
private long type_fonts_ofs_pos;
|
||||
|
||||
public long getBase_ofs_pos() {
|
||||
return base_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_end_ofs_pos() {
|
||||
return sequence_end_ofs_pos;
|
||||
}
|
||||
|
||||
public long getFont_end_ofs_pos() {
|
||||
return font_end_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_start1_ofs_pos() {
|
||||
return sequence_start1_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_start2_ofs_pos() {
|
||||
return sequence_start2_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_start3_ofs_pos() {
|
||||
return sequence_start3_ofs_pos;
|
||||
}
|
||||
|
||||
public long getNames_ofs_pos() {
|
||||
return names_ofs_pos;
|
||||
}
|
||||
|
||||
public long getUnk78_ofs_pos() {
|
||||
return unk78_ofs_pos;
|
||||
}
|
||||
|
||||
public long getLast_section_ofs_pos() {
|
||||
return last_section_ofs_pos;
|
||||
}
|
||||
|
||||
public long getFlash_filename_ofs_pos() {
|
||||
return flash_filename_ofs_pos;
|
||||
}
|
||||
|
||||
public long getDecl_strings_ofs_pos() {
|
||||
return decl_strings_ofs_pos;
|
||||
}
|
||||
|
||||
public long getType_fonts_ofs_pos() {
|
||||
return type_fonts_ofs_pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all addresses by inserting gap
|
||||
*
|
||||
* @param pos Position to insert bytes
|
||||
* @param size Number of bytes
|
||||
*/
|
||||
public void insertGapAfter(long pos, long size) {
|
||||
for (Field f : IggyFlashHeader64.class.getDeclaredFields()) {
|
||||
if (f.getName().endsWith("_address")) {
|
||||
try {
|
||||
long val = f.getLong(this);
|
||||
if (val > pos) {
|
||||
long newval = val + size;
|
||||
f.setLong(this, newval);
|
||||
}
|
||||
} catch (IllegalAccessException iex) {
|
||||
//should not happen
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getImported_guid() {
|
||||
return imported_guid;
|
||||
}
|
||||
|
||||
public long getBaseAddress() {
|
||||
return base_address;
|
||||
}
|
||||
|
||||
public long getSequenceEndAddress() {
|
||||
return sequence_end_address;
|
||||
}
|
||||
|
||||
public long getFontEndAddress() {
|
||||
return font_end_address;
|
||||
}
|
||||
|
||||
public void setFontEndAddress(long val) {
|
||||
this.font_end_address = val;
|
||||
}
|
||||
|
||||
public long getSequenceStartAddress1() {
|
||||
return sequence_start_address1;
|
||||
}
|
||||
|
||||
public long getSequenceStartAddress2() {
|
||||
return sequence_start_address2;
|
||||
}
|
||||
|
||||
public long getSequenceStartAddress3() {
|
||||
return sequence_start_address3;
|
||||
}
|
||||
|
||||
public long getNamesAddress() {
|
||||
return names_address;
|
||||
}
|
||||
|
||||
public long getUnk78Address() {
|
||||
return unk78_address;
|
||||
}
|
||||
|
||||
public long getLastSectionAddress() {
|
||||
return last_section_address;
|
||||
}
|
||||
|
||||
public long getFlashFilenameAddress() {
|
||||
return flash_filename_address;
|
||||
}
|
||||
|
||||
public long getDeclStringsAddress() {
|
||||
return decl_strings_address;
|
||||
}
|
||||
|
||||
public long getTypeFontsAddress() {
|
||||
return type_fonts_address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
base_ofs_pos = stream.position();
|
||||
off_base = stream.readUI64();
|
||||
base_address = off_base == 1 ? 0 : off_base + stream.position() - 8;
|
||||
|
||||
sequence_end_ofs_pos = stream.position();
|
||||
off_sequence_end = stream.readUI64();
|
||||
sequence_end_address = off_sequence_end == 1 ? 0 : off_sequence_end + stream.position() - 8;
|
||||
|
||||
font_end_ofs_pos = stream.position();
|
||||
off_font_end = stream.readUI64();
|
||||
font_end_address = off_font_end == 1 ? 0 : off_font_end + stream.position() - 8;
|
||||
|
||||
sequence_start1_ofs_pos = stream.position();
|
||||
off_sequence_start1 = stream.readUI64();
|
||||
sequence_start_address1 = off_sequence_start1 == 1 ? 0 : off_sequence_start1 + stream.position() - 8;
|
||||
|
||||
sequence_start2_ofs_pos = stream.position();
|
||||
off_sequence_start2 = stream.readUI64();
|
||||
sequence_start_address2 = off_sequence_start2 == 1 ? 0 : off_sequence_start2 + stream.position() - 8;
|
||||
|
||||
sequence_start3_ofs_pos = stream.position();
|
||||
off_sequence_start3 = stream.readUI64();
|
||||
sequence_start_address3 = off_sequence_start3 == 1 ? 0 : off_sequence_start3 + stream.position() - 8;
|
||||
|
||||
xmin = stream.readUI32();
|
||||
ymin = stream.readUI32();
|
||||
xmax = stream.readUI32();
|
||||
ymax = stream.readUI32();
|
||||
|
||||
unk_40 = stream.readUI32(); // probably number of blocks/objects after header
|
||||
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();
|
||||
imported_guid = stream.readUI64();
|
||||
my_guid = stream.readUI64();
|
||||
|
||||
names_ofs_pos = stream.position();
|
||||
off_names = stream.readUI64();
|
||||
names_address = off_names == 1 ? 0 : off_names + stream.position() - 8;
|
||||
|
||||
unk78_ofs_pos = stream.position();
|
||||
off_unk78 = stream.readUI64();
|
||||
unk78_address = off_unk78 == 1 ? 0 : off_unk78 + stream.position() - 8;
|
||||
|
||||
unk80 = stream.readUI64(); //Maybe number of imports/names pointed by names_offset
|
||||
|
||||
last_section_ofs_pos = stream.position();
|
||||
off_last_section = stream.readUI64();
|
||||
last_section_address = off_last_section == 1 ? 0 : off_last_section + stream.position() - 8;
|
||||
|
||||
flash_filename_ofs_pos = stream.position();
|
||||
off_flash_filename = stream.readUI64();
|
||||
flash_filename_address = off_flash_filename == 1 ? 0 : off_flash_filename + stream.position() - 8;
|
||||
|
||||
decl_strings_ofs_pos = stream.position();
|
||||
off_decl_strings = stream.readUI64(); //relative offset to as3 code (16 bytes header + abc blob)
|
||||
decl_strings_address = off_decl_strings == 1 ? 0 : off_decl_strings + stream.position() - 8;
|
||||
|
||||
type_fonts_ofs_pos = stream.position();
|
||||
off_type_of_fonts = stream.readUI64(); //relative offset to as3 file names table (or classes names or whatever)
|
||||
type_fonts_address = off_type_of_fonts == 1 ? 0 : off_type_of_fonts + stream.position() - 8;
|
||||
|
||||
flags = stream.readUI64();
|
||||
font_count = stream.readUI32();
|
||||
zero2 = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
off_base = base_address == 0 ? 1 : base_address - stream.position();
|
||||
stream.writeUI64(off_base);
|
||||
off_sequence_end = sequence_end_address == 0 ? 1 : sequence_end_address - stream.position();
|
||||
stream.writeUI64(off_sequence_end);
|
||||
off_font_end = font_end_address == 0 ? 1 : font_end_address - stream.position();
|
||||
stream.writeUI64(off_font_end);
|
||||
off_sequence_start1 = sequence_start_address1 == 0 ? 1 : sequence_start_address1 - stream.position();
|
||||
stream.writeUI64(off_sequence_start1);
|
||||
off_sequence_start2 = sequence_start_address2 == 0 ? 1 : sequence_start_address2 - stream.position();
|
||||
stream.writeUI64(off_sequence_start2);
|
||||
off_sequence_start3 = sequence_start_address3 == 0 ? 1 : sequence_start_address3 - stream.position();
|
||||
stream.writeUI64(off_sequence_start3);
|
||||
stream.writeUI32(xmin);
|
||||
stream.writeUI32(ymin);
|
||||
stream.writeUI32(xmax);
|
||||
stream.writeUI32(ymax);
|
||||
stream.writeUI32(unk_40);
|
||||
stream.writeUI32(unk_44);
|
||||
stream.writeUI32(unk_48);
|
||||
stream.writeUI32(unk_4C);
|
||||
stream.writeUI32(unk_50);
|
||||
stream.writeUI32(unk_54);
|
||||
stream.writeFloat(frame_rate);
|
||||
stream.writeUI32(unk_5C);
|
||||
stream.writeUI64(imported_guid);
|
||||
stream.writeUI64(my_guid);
|
||||
off_names = names_address == 0 ? 1 : names_address - stream.position();
|
||||
stream.writeUI64(off_names);
|
||||
off_unk78 = unk78_address == 0 ? 1 : unk78_address - stream.position();
|
||||
stream.writeUI64(off_unk78);
|
||||
stream.writeUI64(unk80);
|
||||
off_last_section = last_section_address == 0 ? 1 : last_section_address - stream.position();
|
||||
stream.writeUI64(off_last_section);
|
||||
off_flash_filename = flash_filename_address == 0 ? 1 : flash_filename_address - stream.position();
|
||||
stream.writeUI64(off_flash_filename);
|
||||
off_decl_strings = decl_strings_address == 0 ? 1 : decl_strings_address - stream.position();
|
||||
stream.writeUI64(off_decl_strings);
|
||||
off_type_of_fonts = type_fonts_address == 0 ? 1 : type_fonts_address - stream.position();
|
||||
stream.writeUI64(off_type_of_fonts);
|
||||
stream.writeUI64(flags);
|
||||
stream.writeUI32(font_count);
|
||||
stream.writeUI32(zero2);
|
||||
|
||||
stream.getIndexing().writeLengthCustom(184, new int[]{0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x34, 0x38, 0x3C, 0x40, 0x44, 0x48, 0x4C, 0x50, 0x58, 0x70, 0x78, 0x80, 0x84, 0x88, 0x90, 0x98, 0xA0, 0xB0}, new int[]{2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, 2, 2, 2, 5});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return FieldPrinter.getObjectSummary(this);
|
||||
}
|
||||
|
||||
@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.FieldPrinter;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyFlashHeader64 implements IggyFlashHeaderInterface {
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_base; // 0 Relative offset to first section (matches sizeof header);
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_end; // 8 Relative offset to as3 file names table...
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_font_end; // 0x10 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_start1; // 0x18 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_start2; // 0x20 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_sequence_start3; // 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 imported_guid;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long my_guid; // same for some fonts (eng + chinese)
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_names; // 0x70 relative offset to the names/import section of the file - end of fonts
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_unk78; // 0x78 relative offset to something
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long unk80;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_last_section;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_flash_filename;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_decl_strings;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long off_type_of_fonts;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long flags;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long font_count;
|
||||
@IggyFieldType(DataType.uint32_t)
|
||||
long zero2;
|
||||
|
||||
// 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(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
private long base_address;
|
||||
private long sequence_end_address;
|
||||
private long font_end_address;
|
||||
private long sequence_start_address1;
|
||||
private long sequence_start_address2;
|
||||
private long sequence_start_address3;
|
||||
private long names_address;
|
||||
private long unk78_address;
|
||||
private long last_section_address;
|
||||
private long flash_filename_address;
|
||||
private long decl_strings_address;
|
||||
private long type_fonts_address;
|
||||
|
||||
private long base_ofs_pos;
|
||||
private long sequence_end_ofs_pos;
|
||||
private long font_end_ofs_pos;
|
||||
private long sequence_start1_ofs_pos;
|
||||
private long sequence_start2_ofs_pos;
|
||||
private long sequence_start3_ofs_pos;
|
||||
private long names_ofs_pos;
|
||||
private long unk78_ofs_pos;
|
||||
private long last_section_ofs_pos;
|
||||
private long flash_filename_ofs_pos;
|
||||
private long decl_strings_ofs_pos;
|
||||
private long type_fonts_ofs_pos;
|
||||
|
||||
public long getBase_ofs_pos() {
|
||||
return base_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_end_ofs_pos() {
|
||||
return sequence_end_ofs_pos;
|
||||
}
|
||||
|
||||
public long getFont_end_ofs_pos() {
|
||||
return font_end_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_start1_ofs_pos() {
|
||||
return sequence_start1_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_start2_ofs_pos() {
|
||||
return sequence_start2_ofs_pos;
|
||||
}
|
||||
|
||||
public long getSequence_start3_ofs_pos() {
|
||||
return sequence_start3_ofs_pos;
|
||||
}
|
||||
|
||||
public long getNames_ofs_pos() {
|
||||
return names_ofs_pos;
|
||||
}
|
||||
|
||||
public long getUnk78_ofs_pos() {
|
||||
return unk78_ofs_pos;
|
||||
}
|
||||
|
||||
public long getLast_section_ofs_pos() {
|
||||
return last_section_ofs_pos;
|
||||
}
|
||||
|
||||
public long getFlash_filename_ofs_pos() {
|
||||
return flash_filename_ofs_pos;
|
||||
}
|
||||
|
||||
public long getDecl_strings_ofs_pos() {
|
||||
return decl_strings_ofs_pos;
|
||||
}
|
||||
|
||||
public long getType_fonts_ofs_pos() {
|
||||
return type_fonts_ofs_pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all addresses by inserting gap
|
||||
*
|
||||
* @param pos Position to insert bytes
|
||||
* @param size Number of bytes
|
||||
*/
|
||||
public void insertGapAfter(long pos, long size) {
|
||||
for (Field f : IggyFlashHeader64.class.getDeclaredFields()) {
|
||||
if (f.getName().endsWith("_address")) {
|
||||
try {
|
||||
long val = f.getLong(this);
|
||||
if (val > pos) {
|
||||
long newval = val + size;
|
||||
f.setLong(this, newval);
|
||||
}
|
||||
} catch (IllegalAccessException iex) {
|
||||
//should not happen
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getImported_guid() {
|
||||
return imported_guid;
|
||||
}
|
||||
|
||||
public long getBaseAddress() {
|
||||
return base_address;
|
||||
}
|
||||
|
||||
public long getSequenceEndAddress() {
|
||||
return sequence_end_address;
|
||||
}
|
||||
|
||||
public long getFontEndAddress() {
|
||||
return font_end_address;
|
||||
}
|
||||
|
||||
public void setFontEndAddress(long val) {
|
||||
this.font_end_address = val;
|
||||
}
|
||||
|
||||
public long getSequenceStartAddress1() {
|
||||
return sequence_start_address1;
|
||||
}
|
||||
|
||||
public long getSequenceStartAddress2() {
|
||||
return sequence_start_address2;
|
||||
}
|
||||
|
||||
public long getSequenceStartAddress3() {
|
||||
return sequence_start_address3;
|
||||
}
|
||||
|
||||
public long getNamesAddress() {
|
||||
return names_address;
|
||||
}
|
||||
|
||||
public long getUnk78Address() {
|
||||
return unk78_address;
|
||||
}
|
||||
|
||||
public long getLastSectionAddress() {
|
||||
return last_section_address;
|
||||
}
|
||||
|
||||
public long getFlashFilenameAddress() {
|
||||
return flash_filename_address;
|
||||
}
|
||||
|
||||
public long getDeclStringsAddress() {
|
||||
return decl_strings_address;
|
||||
}
|
||||
|
||||
public long getTypeFontsAddress() {
|
||||
return type_fonts_address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
base_ofs_pos = stream.position();
|
||||
off_base = stream.readUI64();
|
||||
base_address = off_base == 1 ? 0 : off_base + stream.position() - 8;
|
||||
|
||||
sequence_end_ofs_pos = stream.position();
|
||||
off_sequence_end = stream.readUI64();
|
||||
sequence_end_address = off_sequence_end == 1 ? 0 : off_sequence_end + stream.position() - 8;
|
||||
|
||||
font_end_ofs_pos = stream.position();
|
||||
off_font_end = stream.readUI64();
|
||||
font_end_address = off_font_end == 1 ? 0 : off_font_end + stream.position() - 8;
|
||||
|
||||
sequence_start1_ofs_pos = stream.position();
|
||||
off_sequence_start1 = stream.readUI64();
|
||||
sequence_start_address1 = off_sequence_start1 == 1 ? 0 : off_sequence_start1 + stream.position() - 8;
|
||||
|
||||
sequence_start2_ofs_pos = stream.position();
|
||||
off_sequence_start2 = stream.readUI64();
|
||||
sequence_start_address2 = off_sequence_start2 == 1 ? 0 : off_sequence_start2 + stream.position() - 8;
|
||||
|
||||
sequence_start3_ofs_pos = stream.position();
|
||||
off_sequence_start3 = stream.readUI64();
|
||||
sequence_start_address3 = off_sequence_start3 == 1 ? 0 : off_sequence_start3 + stream.position() - 8;
|
||||
|
||||
xmin = stream.readUI32();
|
||||
ymin = stream.readUI32();
|
||||
xmax = stream.readUI32();
|
||||
ymax = stream.readUI32();
|
||||
|
||||
unk_40 = stream.readUI32(); // probably number of blocks/objects after header
|
||||
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();
|
||||
imported_guid = stream.readUI64();
|
||||
my_guid = stream.readUI64();
|
||||
|
||||
names_ofs_pos = stream.position();
|
||||
off_names = stream.readUI64();
|
||||
names_address = off_names == 1 ? 0 : off_names + stream.position() - 8;
|
||||
|
||||
unk78_ofs_pos = stream.position();
|
||||
off_unk78 = stream.readUI64();
|
||||
unk78_address = off_unk78 == 1 ? 0 : off_unk78 + stream.position() - 8;
|
||||
|
||||
unk80 = stream.readUI64(); //Maybe number of imports/names pointed by names_offset
|
||||
|
||||
last_section_ofs_pos = stream.position();
|
||||
off_last_section = stream.readUI64();
|
||||
last_section_address = off_last_section == 1 ? 0 : off_last_section + stream.position() - 8;
|
||||
|
||||
flash_filename_ofs_pos = stream.position();
|
||||
off_flash_filename = stream.readUI64();
|
||||
flash_filename_address = off_flash_filename == 1 ? 0 : off_flash_filename + stream.position() - 8;
|
||||
|
||||
decl_strings_ofs_pos = stream.position();
|
||||
off_decl_strings = stream.readUI64(); //relative offset to as3 code (16 bytes header + abc blob)
|
||||
decl_strings_address = off_decl_strings == 1 ? 0 : off_decl_strings + stream.position() - 8;
|
||||
|
||||
type_fonts_ofs_pos = stream.position();
|
||||
off_type_of_fonts = stream.readUI64(); //relative offset to as3 file names table (or classes names or whatever)
|
||||
type_fonts_address = off_type_of_fonts == 1 ? 0 : off_type_of_fonts + stream.position() - 8;
|
||||
|
||||
flags = stream.readUI64();
|
||||
font_count = stream.readUI32();
|
||||
zero2 = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
off_base = base_address == 0 ? 1 : base_address - stream.position();
|
||||
stream.writeUI64(off_base);
|
||||
off_sequence_end = sequence_end_address == 0 ? 1 : sequence_end_address - stream.position();
|
||||
stream.writeUI64(off_sequence_end);
|
||||
off_font_end = font_end_address == 0 ? 1 : font_end_address - stream.position();
|
||||
stream.writeUI64(off_font_end);
|
||||
off_sequence_start1 = sequence_start_address1 == 0 ? 1 : sequence_start_address1 - stream.position();
|
||||
stream.writeUI64(off_sequence_start1);
|
||||
off_sequence_start2 = sequence_start_address2 == 0 ? 1 : sequence_start_address2 - stream.position();
|
||||
stream.writeUI64(off_sequence_start2);
|
||||
off_sequence_start3 = sequence_start_address3 == 0 ? 1 : sequence_start_address3 - stream.position();
|
||||
stream.writeUI64(off_sequence_start3);
|
||||
stream.writeUI32(xmin);
|
||||
stream.writeUI32(ymin);
|
||||
stream.writeUI32(xmax);
|
||||
stream.writeUI32(ymax);
|
||||
stream.writeUI32(unk_40);
|
||||
stream.writeUI32(unk_44);
|
||||
stream.writeUI32(unk_48);
|
||||
stream.writeUI32(unk_4C);
|
||||
stream.writeUI32(unk_50);
|
||||
stream.writeUI32(unk_54);
|
||||
stream.writeFloat(frame_rate);
|
||||
stream.writeUI32(unk_5C);
|
||||
stream.writeUI64(imported_guid);
|
||||
stream.writeUI64(my_guid);
|
||||
off_names = names_address == 0 ? 1 : names_address - stream.position();
|
||||
stream.writeUI64(off_names);
|
||||
off_unk78 = unk78_address == 0 ? 1 : unk78_address - stream.position();
|
||||
stream.writeUI64(off_unk78);
|
||||
stream.writeUI64(unk80);
|
||||
off_last_section = last_section_address == 0 ? 1 : last_section_address - stream.position();
|
||||
stream.writeUI64(off_last_section);
|
||||
off_flash_filename = flash_filename_address == 0 ? 1 : flash_filename_address - stream.position();
|
||||
stream.writeUI64(off_flash_filename);
|
||||
off_decl_strings = decl_strings_address == 0 ? 1 : decl_strings_address - stream.position();
|
||||
stream.writeUI64(off_decl_strings);
|
||||
off_type_of_fonts = type_fonts_address == 0 ? 1 : type_fonts_address - stream.position();
|
||||
stream.writeUI64(off_type_of_fonts);
|
||||
stream.writeUI64(flags);
|
||||
stream.writeUI32(font_count);
|
||||
stream.writeUI32(zero2);
|
||||
|
||||
stream.getIndexing().writeLengthCustom(184, new int[]{0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x34, 0x38, 0x3C, 0x40, 0x44, 0x48, 0x4C, 0x50, 0x58, 0x70, 0x78, 0x80, 0x84, 0x88, 0x90, 0x98, 0xA0, 0xB0}, new int[]{2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, 2, 2, 2, 5});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return FieldPrinter.getObjectSummary(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMin() {
|
||||
return xmin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMin() {
|
||||
return ymin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getXMax() {
|
||||
return xmax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getYMax() {
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrameRate() {
|
||||
return frame_rate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @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;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface IggyFlashHeaderInterface extends StructureInterface {
|
||||
|
||||
public long getXMin();
|
||||
|
||||
public long getYMin();
|
||||
|
||||
public long getXMax();
|
||||
|
||||
public long getYMax();
|
||||
|
||||
public float getFrameRate();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,83 +1,83 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyFontBinInfo implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 96;
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long size_of_this_info = STRUCT_SIZE;
|
||||
@IggyFieldType(value = DataType.uint16_t, count = 4)
|
||||
int font_specific[];
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float normX;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float zero;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float zero2;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float normY;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float minSize;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float maxSize;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long order_in_iggy_file;
|
||||
@IggyFieldType(DataType.int64_t)
|
||||
long address_back; //relative
|
||||
@IggyFieldType(value = DataType.uint8_t, count = 40)
|
||||
byte pad[];
|
||||
|
||||
public IggyFontBinInfo(ReadDataStreamInterface s) throws IOException {
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
size_of_this_info = s.readUI64();
|
||||
if (size_of_this_info != 96) {
|
||||
throw new IOException(String.format("Wrong iggy font format (bininfo)!"));
|
||||
}
|
||||
font_specific = new int[4];
|
||||
for (int i = 0; i < font_specific.length; i++) {
|
||||
font_specific[i] = s.readUI16();
|
||||
}
|
||||
normX = s.readFloat();
|
||||
zero = s.readFloat();
|
||||
zero2 = s.readFloat();
|
||||
normY = s.readFloat();
|
||||
minSize = s.readFloat();
|
||||
maxSize = s.readFloat();
|
||||
order_in_iggy_file = s.readUI64();
|
||||
address_back = s.readSI64();
|
||||
//if(address_back + s.position() - 8 != text_offsets[i]) Printf("Wrong iggy font format (bininfo-offsetback) (%u)!\n",i);
|
||||
pad = s.readBytes(40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeUI64(size_of_this_info);
|
||||
for (int i = 0; i < font_specific.length; i++) {
|
||||
s.writeUI16(font_specific[i]);
|
||||
}
|
||||
s.writeFloat(normX);
|
||||
s.writeFloat(zero);
|
||||
s.writeFloat(zero2);
|
||||
s.writeFloat(normY);
|
||||
s.writeFloat(minSize);
|
||||
s.writeFloat(maxSize);
|
||||
s.writeUI64(order_in_iggy_file);
|
||||
s.writeSI64(address_back);
|
||||
s.writeBytes(pad);
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyFontBinInfo implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 96;
|
||||
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long size_of_this_info = STRUCT_SIZE;
|
||||
@IggyFieldType(value = DataType.uint16_t, count = 4)
|
||||
int font_specific[];
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float normX;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float zero;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float zero2;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float normY;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float minSize;
|
||||
@IggyFieldType(DataType.float_t)
|
||||
float maxSize;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long order_in_iggy_file;
|
||||
@IggyFieldType(DataType.int64_t)
|
||||
long address_back; //relative
|
||||
@IggyFieldType(value = DataType.uint8_t, count = 40)
|
||||
byte pad[];
|
||||
|
||||
public IggyFontBinInfo(ReadDataStreamInterface s) throws IOException {
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
size_of_this_info = s.readUI64();
|
||||
if (size_of_this_info != 96) {
|
||||
throw new IOException(String.format("Wrong iggy font format (bininfo)!"));
|
||||
}
|
||||
font_specific = new int[4];
|
||||
for (int i = 0; i < font_specific.length; i++) {
|
||||
font_specific[i] = s.readUI16();
|
||||
}
|
||||
normX = s.readFloat();
|
||||
zero = s.readFloat();
|
||||
zero2 = s.readFloat();
|
||||
normY = s.readFloat();
|
||||
minSize = s.readFloat();
|
||||
maxSize = s.readFloat();
|
||||
order_in_iggy_file = s.readUI64();
|
||||
address_back = s.readSI64();
|
||||
//if(address_back + s.position() - 8 != text_offsets[i]) Printf("Wrong iggy font format (bininfo-offsetback) (%u)!\n",i);
|
||||
pad = s.readBytes(40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeUI64(size_of_this_info);
|
||||
for (int i = 0; i < font_specific.length; i++) {
|
||||
s.writeUI16(font_specific[i]);
|
||||
}
|
||||
s.writeFloat(normX);
|
||||
s.writeFloat(zero);
|
||||
s.writeFloat(zero2);
|
||||
s.writeFloat(normY);
|
||||
s.writeFloat(minSize);
|
||||
s.writeFloat(maxSize);
|
||||
s.writeUI64(order_in_iggy_file);
|
||||
s.writeSI64(address_back);
|
||||
s.writeBytes(pad);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyFontTypeInfo implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 24;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long ofs_local_name;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long font_info_num;
|
||||
|
||||
private long local_name_ofs_pos;
|
||||
|
||||
public long getLocal_name_ofs_pos() {
|
||||
return local_name_ofs_pos;
|
||||
}
|
||||
|
||||
public IggyFontTypeInfo(ReadDataStreamInterface s) throws IOException {
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
zero = s.readUI64();
|
||||
local_name_ofs_pos = s.position();
|
||||
ofs_local_name = s.readUI64();
|
||||
font_info_num = s.readUI64();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeUI64(zero);
|
||||
local_name_ofs_pos = s.position();
|
||||
s.writeUI64(ofs_local_name);
|
||||
s.writeUI64(font_info_num);
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyFontTypeInfo implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 24;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long zero;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long ofs_local_name;
|
||||
@IggyFieldType(DataType.uint64_t)
|
||||
long font_info_num;
|
||||
|
||||
private long local_name_ofs_pos;
|
||||
|
||||
public long getLocal_name_ofs_pos() {
|
||||
return local_name_ofs_pos;
|
||||
}
|
||||
|
||||
public IggyFontTypeInfo(ReadDataStreamInterface s) throws IOException {
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
zero = s.readUI64();
|
||||
local_name_ofs_pos = s.position();
|
||||
ofs_local_name = s.readUI64();
|
||||
font_info_num = s.readUI64();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeUI64(zero);
|
||||
local_name_ofs_pos = s.position();
|
||||
s.writeUI64(ofs_local_name);
|
||||
s.writeUI64(font_info_num);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,166 +1,166 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyArrayFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* little endian all
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyHeader implements StructureInterface {
|
||||
|
||||
public static int STRUCT_SIZE = 32;
|
||||
|
||||
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(ReadDataStreamInterface 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(ReadDataStreamInterface 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(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeUI32(magic);
|
||||
s.writeUI32(version);
|
||||
s.writeUI8(platform1);
|
||||
s.writeUI8(platform2);
|
||||
s.writeUI8(platform3);
|
||||
s.writeUI8(platform4);
|
||||
s.writeUI32(unk_0C);
|
||||
s.writeBytes(reserved);
|
||||
s.writeUI32(numSubfiles);
|
||||
}
|
||||
|
||||
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 com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* little endian all
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggyHeader implements StructureInterface {
|
||||
|
||||
public static int STRUCT_SIZE = 32;
|
||||
|
||||
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(ReadDataStreamInterface 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(ReadDataStreamInterface 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(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeUI32(magic);
|
||||
s.writeUI32(version);
|
||||
s.writeUI8(platform1);
|
||||
s.writeUI8(platform2);
|
||||
s.writeUI8(platform3);
|
||||
s.writeUI8(platform4);
|
||||
s.writeUI32(unk_0C);
|
||||
s.writeBytes(reserved);
|
||||
s.writeUI32(numSubfiles);
|
||||
}
|
||||
|
||||
public boolean is64() {
|
||||
return platform2 == 64;
|
||||
}
|
||||
|
||||
public long getMagic() {
|
||||
return magic;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public int getPlatform1() {
|
||||
return platform1;
|
||||
}
|
||||
|
||||
public int getPlatform2() {
|
||||
return platform2;
|
||||
}
|
||||
|
||||
public int getPlatform3() {
|
||||
return platform3;
|
||||
}
|
||||
|
||||
public int getPlatform4() {
|
||||
return platform4;
|
||||
}
|
||||
|
||||
public long getUnk_0C() {
|
||||
return unk_0C;
|
||||
}
|
||||
|
||||
public byte[] getReserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public long getNumSubfiles() {
|
||||
return numSubfiles;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,174 +1,174 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShape implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 64;
|
||||
|
||||
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;
|
||||
|
||||
public IggyShape(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyShape(float minx, float miny, float maxx, float maxy, List<IggyShapeNode> nodes) {
|
||||
this.minx = minx;
|
||||
this.miny = miny;
|
||||
this.maxx = maxx;
|
||||
this.maxy = maxy;
|
||||
this.unk = 0; //??
|
||||
this.one = 1;
|
||||
this.one2 = 1;
|
||||
this.one3 = 1;
|
||||
this.one4 = 1;
|
||||
this.two1 = 2;
|
||||
this.count = nodes.size();
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
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 one: %d, one2: %d, one3: %d, one4: %d, two1: %d\n", 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(WriteDataStreamInterface s) throws IOException {
|
||||
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_SHAPE_SIZE);
|
||||
s.writeFloat(minx);
|
||||
s.writeFloat(miny);
|
||||
s.writeFloat(maxx);
|
||||
s.writeFloat(maxy);
|
||||
s.writeUI64(unk);
|
||||
s.writeUI64(count);
|
||||
s.writeUI64(one);
|
||||
s.writeUI64(one2);
|
||||
s.writeUI64(one3);
|
||||
s.writeUI32(one4);
|
||||
s.writeUI32(two1);
|
||||
|
||||
s.getIndexing().writeConstLengthArray(IggyIndexBuilder.CONST_SHAPE_NODE_SIZE, nodes.size());
|
||||
|
||||
for (IggyShapeNode node : nodes) {
|
||||
node.writeToDataStream(s);
|
||||
}
|
||||
}
|
||||
|
||||
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 com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShape implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 64;
|
||||
|
||||
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;
|
||||
|
||||
public IggyShape(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
public IggyShape(float minx, float miny, float maxx, float maxy, List<IggyShapeNode> nodes) {
|
||||
this.minx = minx;
|
||||
this.miny = miny;
|
||||
this.maxx = maxx;
|
||||
this.maxy = maxy;
|
||||
this.unk = 0; //??
|
||||
this.one = 1;
|
||||
this.one2 = 1;
|
||||
this.one3 = 1;
|
||||
this.one4 = 1;
|
||||
this.two1 = 2;
|
||||
this.count = nodes.size();
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
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 one: %d, one2: %d, one3: %d, one4: %d, two1: %d\n", 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(WriteDataStreamInterface s) throws IOException {
|
||||
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_SHAPE_SIZE);
|
||||
s.writeFloat(minx);
|
||||
s.writeFloat(miny);
|
||||
s.writeFloat(maxx);
|
||||
s.writeFloat(maxy);
|
||||
s.writeUI64(unk);
|
||||
s.writeUI64(count);
|
||||
s.writeUI64(one);
|
||||
s.writeUI64(one2);
|
||||
s.writeUI64(one3);
|
||||
s.writeUI32(one4);
|
||||
s.writeUI32(two1);
|
||||
|
||||
s.getIndexing().writeConstLengthArray(IggyIndexBuilder.CONST_SHAPE_NODE_SIZE, nodes.size());
|
||||
|
||||
for (IggyShapeNode node : nodes) {
|
||||
node.writeToDataStream(s);
|
||||
}
|
||||
}
|
||||
|
||||
public float getMinx() {
|
||||
return minx;
|
||||
}
|
||||
|
||||
public float getMiny() {
|
||||
return miny;
|
||||
}
|
||||
|
||||
public float getMaxx() {
|
||||
return maxx;
|
||||
}
|
||||
|
||||
public float getMaxy() {
|
||||
return maxy;
|
||||
}
|
||||
|
||||
public long getUnk() {
|
||||
return unk;
|
||||
}
|
||||
|
||||
public long getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public long getOne2() {
|
||||
return one2;
|
||||
}
|
||||
|
||||
public long getOne3() {
|
||||
return one3;
|
||||
}
|
||||
|
||||
public long getOne4() {
|
||||
return one4;
|
||||
}
|
||||
|
||||
public long getTwo1() {
|
||||
return two1;
|
||||
}
|
||||
|
||||
public List<IggyShapeNode> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,135 +1,135 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShapeNode implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 24;
|
||||
|
||||
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 targetX, float targetY, float controlX, float controlY, int node_type, int node_subtype, boolean first) {
|
||||
this.targetX = targetX;
|
||||
this.targetY = targetY;
|
||||
this.controlX = controlX;
|
||||
this.controlY = controlY;
|
||||
this.node_type = node_type;
|
||||
this.node_subtype = node_subtype;
|
||||
this.zer1 = 0;
|
||||
this.zer2 = 0;
|
||||
this.first = first;
|
||||
this.isstart = first ? 0 : 1;
|
||||
}
|
||||
|
||||
public IggyShapeNode(ReadDataStreamInterface s, boolean first) throws IOException {
|
||||
this.first = first;
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeFloat(targetX);
|
||||
s.writeFloat(targetY);
|
||||
s.writeFloat(controlX);
|
||||
s.writeFloat(controlY);
|
||||
s.writeUI8(node_type);
|
||||
s.writeUI8(node_subtype);
|
||||
s.writeUI8(zer1);
|
||||
s.writeUI8(zer2);
|
||||
s.writeUI32(isstart);
|
||||
}
|
||||
|
||||
public float getTargetX() {
|
||||
return targetX;
|
||||
}
|
||||
|
||||
public float getTargetY() {
|
||||
return targetY;
|
||||
}
|
||||
|
||||
public float getControlX() {
|
||||
return controlX;
|
||||
}
|
||||
|
||||
public float getControlY() {
|
||||
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 com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyShapeNode implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 24;
|
||||
|
||||
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 targetX, float targetY, float controlX, float controlY, int node_type, int node_subtype, boolean first) {
|
||||
this.targetX = targetX;
|
||||
this.targetY = targetY;
|
||||
this.controlX = controlX;
|
||||
this.controlY = controlY;
|
||||
this.node_type = node_type;
|
||||
this.node_subtype = node_subtype;
|
||||
this.zer1 = 0;
|
||||
this.zer2 = 0;
|
||||
this.first = first;
|
||||
this.isstart = first ? 0 : 1;
|
||||
}
|
||||
|
||||
public IggyShapeNode(ReadDataStreamInterface s, boolean first) throws IOException {
|
||||
this.first = first;
|
||||
readFromDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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(WriteDataStreamInterface s) throws IOException {
|
||||
s.writeFloat(targetX);
|
||||
s.writeFloat(targetY);
|
||||
s.writeFloat(controlX);
|
||||
s.writeFloat(controlY);
|
||||
s.writeUI8(node_type);
|
||||
s.writeUI8(node_subtype);
|
||||
s.writeUI8(zer1);
|
||||
s.writeUI8(zer2);
|
||||
s.writeUI32(isstart);
|
||||
}
|
||||
|
||||
public float getTargetX() {
|
||||
return targetX;
|
||||
}
|
||||
|
||||
public float getTargetY() {
|
||||
return targetY;
|
||||
}
|
||||
|
||||
public float getControlX() {
|
||||
return controlX;
|
||||
}
|
||||
|
||||
public float getControlY() {
|
||||
return controlY;
|
||||
}
|
||||
|
||||
public int getNodeType() {
|
||||
return node_type;
|
||||
}
|
||||
|
||||
public int getNodeSubType() {
|
||||
return node_subtype;
|
||||
}
|
||||
|
||||
public int getZer1() {
|
||||
return zer1;
|
||||
}
|
||||
|
||||
public int getZer2() {
|
||||
return zer2;
|
||||
}
|
||||
|
||||
public boolean isStart() {
|
||||
return isstart == 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,76 +1,76 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggySubFileEntry implements StructureInterface {
|
||||
|
||||
public static final int STRUCTURE_SIZE = 16;
|
||||
|
||||
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(ReadDataStreamInterface 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(ReadDataStreamInterface stream) throws IOException {
|
||||
type = stream.readUI32();
|
||||
size = stream.readUI32();
|
||||
size2 = stream.readUI32();
|
||||
offset = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
stream.writeUI32(type);
|
||||
stream.writeUI32(size);
|
||||
stream.writeUI32(size2);
|
||||
stream.writeUI32(offset);
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*
|
||||
* Based of works of somebody called eternity.
|
||||
*/
|
||||
public class IggySubFileEntry implements StructureInterface {
|
||||
|
||||
public static final int STRUCTURE_SIZE = 16;
|
||||
|
||||
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(ReadDataStreamInterface 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(ReadDataStreamInterface stream) throws IOException {
|
||||
type = stream.readUI32();
|
||||
size = stream.readUI32();
|
||||
size2 = stream.readUI32();
|
||||
offset = stream.readUI32();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
stream.writeUI32(type);
|
||||
stream.writeUI32(size);
|
||||
stream.writeUI32(size2);
|
||||
stream.writeUI32(offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,319 +1,319 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.annotations.IggyFieldType;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggySwf implements StructureInterface {
|
||||
|
||||
final static int NO_OFFSET = 1;
|
||||
|
||||
@IggyFieldType(value = DataType.wchar_t, count = 48)
|
||||
String name;
|
||||
|
||||
List<IggyFont> fonts = new ArrayList<>();
|
||||
// private List<Long> font_data_addresses = new ArrayList<>();
|
||||
List<IggyFont> add_fonts = new ArrayList<>();
|
||||
// private List<Long> add_font_data_addresses = new ArrayList<>();
|
||||
|
||||
private IggyFlashHeader64 hdr;
|
||||
|
||||
public IggySwf(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
private List<IggyText> texts = new ArrayList<>();
|
||||
//private List<Long> text_data_addresses = new ArrayList<>();
|
||||
private List<IggyText> add_texts = new ArrayList<>();
|
||||
//private List<Long> add_text_data_addresses = new ArrayList<>();
|
||||
|
||||
//private byte font_add_data[];
|
||||
//private List<Long> font_additional_size = new ArrayList<>();
|
||||
private IggyFontBinInfo font_bin_info[];
|
||||
private List<String> sequenceNames = new ArrayList<>();
|
||||
//private List<Long> sequenceValues = new ArrayList<>();
|
||||
|
||||
private IggyFontTypeInfo type_info[];
|
||||
private String type_info_name[];
|
||||
private IggyDeclStrings decl_strings;
|
||||
private long ofs_additional;
|
||||
private long additional_address;
|
||||
|
||||
public IggyFlashHeader64 getHdr() {
|
||||
return hdr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
this.hdr = new IggyFlashHeader64(s);
|
||||
//Save all font bytes to buffer for later easy modification
|
||||
//here is offset[0] - 184
|
||||
name = s.readWChar();
|
||||
//here is offset[1] - 230
|
||||
int pad8 = 8 - (int) (s.position() % 8);
|
||||
if (pad8 > 8) {
|
||||
s.seek(pad8, SeekMode.CUR);
|
||||
}
|
||||
//here is offset [2] - 232
|
||||
s.seek(hdr.getBaseAddress(), SeekMode.SET);
|
||||
s.readUI64(); //pad 1
|
||||
|
||||
List<Long> itemsAddresses = new ArrayList<>();
|
||||
|
||||
while (true) {
|
||||
long offset = s.readUI64();
|
||||
if (offset == 1) {
|
||||
break;
|
||||
}
|
||||
itemsAddresses.add(offset + s.position() - 8);
|
||||
}
|
||||
if (hdr.getImported_guid() != 0) {
|
||||
ofs_additional = s.readUI64();
|
||||
additional_address = ofs_additional == 1 ? 0 : ofs_additional + s.position() - 8;
|
||||
}
|
||||
for (Long addr : itemsAddresses) {
|
||||
s.seek(addr, SeekMode.SET);
|
||||
int kind = s.readUI8();
|
||||
s.seek(-1, SeekMode.CUR);
|
||||
switch (kind) {
|
||||
case 22 /*FONT*/:
|
||||
IggyFont font = new IggyFont(s);
|
||||
//font_data_addresses.add(addr);
|
||||
fonts.add(font);
|
||||
break;
|
||||
case 6 /*TEXT*/:
|
||||
IggyText text = new IggyText(s);
|
||||
//text_data_addresses.add(addr);
|
||||
texts.add(text);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown item kind: " + kind);
|
||||
}
|
||||
}
|
||||
|
||||
if (additional_address != 0) {
|
||||
s.seek(additional_address, SeekMode.SET);
|
||||
List<Long> additionalItemsAddresses = new ArrayList<>();
|
||||
while (true) {
|
||||
long offset = s.readUI64();
|
||||
if (offset == 1) {
|
||||
break;
|
||||
}
|
||||
additionalItemsAddresses.add(offset + s.position() - 8);
|
||||
}
|
||||
for (Long addr : additionalItemsAddresses) {
|
||||
s.seek(addr, SeekMode.SET);
|
||||
int kind = s.readUI8();
|
||||
s.seek(-1, SeekMode.CUR);
|
||||
switch (kind) {
|
||||
case 22 /*FONT*/:
|
||||
IggyFont font = new IggyFont(s);
|
||||
//add_font_data_addresses.add(addr);
|
||||
add_fonts.add(font);
|
||||
break;
|
||||
case 6 /*TEXT*/:
|
||||
IggyText text = new IggyText(s);
|
||||
//add_text_data_addresses.add(addr);
|
||||
add_texts.add(text);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown imported item kind: " + kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
s.seek(hdr.getFontEndAddress(), SeekMode.SET);
|
||||
//here is offset [4] - 856 ?
|
||||
font_bin_info = new IggyFontBinInfo[(int) hdr.font_count];
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
font_bin_info[i] = new IggyFontBinInfo(s);
|
||||
}
|
||||
|
||||
sequenceNames = new ArrayList<>();
|
||||
|
||||
long seq_addresses[] = new long[]{hdr.getSequenceStartAddress1(), hdr.getSequenceStartAddress2(), hdr.getSequenceStartAddress3()};
|
||||
long seq_name_addresses[] = new long[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (seq_addresses[i] == 0) {
|
||||
seq_name_addresses[i] = 0;
|
||||
//0
|
||||
} else {
|
||||
s.seek(seq_addresses[i], SeekMode.SET);
|
||||
long ofs_seq_name = s.readUI64();
|
||||
seq_name_addresses[i] = ofs_seq_name == 1 ? 0 : ofs_seq_name + s.position() - 8;
|
||||
s.readUI64(); //is this crucial?
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (seq_name_addresses[i] > 0) {
|
||||
s.seek(seq_name_addresses[i], SeekMode.SET);
|
||||
sequenceNames.add(s.readWChar());
|
||||
} else {
|
||||
sequenceNames.add(null);
|
||||
}
|
||||
}
|
||||
s.pad8bytes();
|
||||
|
||||
//sequence = new IggySequence(s);
|
||||
s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
|
||||
type_info = new IggyFontTypeInfo[(int) hdr.font_count];
|
||||
type_info_name = new String[(int) hdr.font_count];
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
type_info[i] = new IggyFontTypeInfo(s);
|
||||
}
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
s.seek(type_info[i].getLocal_name_ofs_pos() + type_info[i].ofs_local_name, SeekMode.SET);
|
||||
type_info_name[i] = s.readWChar();
|
||||
}
|
||||
|
||||
s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
|
||||
decl_strings = new IggyDeclStrings(s);
|
||||
/*WriteDataStreamInterface outs = new TemporaryDataStream();
|
||||
writeToDataStream(outs);
|
||||
Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\parts\\swf_out.bin", outs.getAllBytes());*/
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
IggyIndexBuilder ib = s.getIndexing();
|
||||
hdr.writeToDataStream(s);
|
||||
s.writeWChar(name);
|
||||
s.pad8bytes();
|
||||
s.writeUI64(1);
|
||||
ib.write16bitArray(name.length() + 1);
|
||||
ib.writeTwoPaddingBytes();
|
||||
ib.write64bitPointerArray(64);
|
||||
long posBeforeOffsets = s.position();
|
||||
|
||||
final int FILL_LATER = 1;
|
||||
|
||||
List<Long> fontPosFillLater = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < fonts.size(); i++) {
|
||||
fontPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
List<Long> textPosFillLater = new ArrayList<>();
|
||||
for (int i = 0; i < texts.size(); i++) {
|
||||
textPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
s.writeUI64(1);
|
||||
|
||||
long addPosFillLater = s.position();
|
||||
s.writeUI64(FILL_LATER);
|
||||
long posAfter = posBeforeOffsets + 64 * 8;
|
||||
long curPos = s.position();
|
||||
long numLeft = posAfter - curPos;
|
||||
long ofsLeft = numLeft / 8;
|
||||
for (int i = 0; i < ofsLeft - 1; i++) {
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
|
||||
for (int i = 0; i < fonts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(fontPosFillLater.get(i));
|
||||
fonts.get(i).writeToDataStream(s);
|
||||
}
|
||||
for (int i = 0; i < texts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(textPosFillLater.get(i));
|
||||
texts.get(i).writeToDataStream(s);
|
||||
}
|
||||
|
||||
if (!add_fonts.isEmpty() || !add_texts.isEmpty()) {
|
||||
s.setOlderOffsetToThisPos(addPosFillLater);
|
||||
|
||||
List<Long> addFontPosFillLater = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < add_fonts.size(); i++) {
|
||||
addFontPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
List<Long> addTextPosFillLater = new ArrayList<>();
|
||||
for (int i = 0; i < add_texts.size(); i++) {
|
||||
addTextPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
s.writeUI64(FILL_LATER);
|
||||
for (int i = 0; i < add_fonts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(addFontPosFillLater.get(i));
|
||||
add_fonts.get(i).writeToDataStream(s);
|
||||
}
|
||||
for (int i = 0; i < add_texts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(addTextPosFillLater.get(i));
|
||||
add_texts.get(i).writeToDataStream(s);
|
||||
}
|
||||
}
|
||||
s.setOlderOffsetToThisPos(hdr.getFont_end_ofs_pos());
|
||||
ib.writeConstLengthArray(IggyIndexBuilder.CONST_BIN_INFO_SIZE, hdr.font_count);
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
font_bin_info[i].writeToDataStream(s);
|
||||
}
|
||||
|
||||
long seq_ofs_pos[] = new long[]{hdr.getSequence_start1_ofs_pos(), hdr.getSequence_start2_ofs_pos(), hdr.getSequence_start3_ofs_pos()};
|
||||
long off_seq_expected[] = new long[]{hdr.off_sequence_start1, hdr.off_sequence_start2, hdr.off_sequence_start3};
|
||||
|
||||
long seq_name_fill_later[] = new long[3];
|
||||
|
||||
s.setOlderOffsetToThisPos(seq_ofs_pos[0]);
|
||||
s.writeUI64(1);
|
||||
s.writeUI64(1);
|
||||
ib.writeLengthCustom(16, new int[]{0}, new int[]{2});
|
||||
|
||||
seq_name_fill_later[2] = s.position();
|
||||
s.setOlderOffsetToThisPos(seq_ofs_pos[2]);
|
||||
s.writeUI64(FILL_LATER);
|
||||
s.writeUI64(0);
|
||||
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (sequenceNames.get(i) != null) {
|
||||
s.setOlderOffsetToThisPos(seq_name_fill_later[i]);
|
||||
ib.write16bitArray(sequenceNames.get(i).length() + 1);
|
||||
s.writeWChar(sequenceNames.get(i));
|
||||
}
|
||||
}
|
||||
s.setOlderOffsetToThisPos(hdr.getSequence_end_ofs_pos());
|
||||
s.pad8bytes();
|
||||
ib.pad8bytes();
|
||||
|
||||
ib.writeConstLengthArray(IggyIndexBuilder.CONST_TYPE_INFO_SIZE, hdr.font_count);
|
||||
s.setOlderOffsetToThisPos(hdr.getType_fonts_ofs_pos());
|
||||
//s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
type_info[i].writeToDataStream(s);
|
||||
}
|
||||
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
ib.write16bitArray(type_info_name[i].length() + 1);
|
||||
s.setOlderOffsetToThisPos(type_info[i].getLocal_name_ofs_pos());
|
||||
s.writeWChar(type_info_name[i]);
|
||||
}
|
||||
s.pad8bytes();
|
||||
ib.pad8bytes();
|
||||
|
||||
s.setOlderOffsetToThisPos(hdr.getDecl_strings_ofs_pos());
|
||||
//s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
|
||||
decl_strings.writeToDataStream(s);
|
||||
}
|
||||
|
||||
@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 com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggySwf implements StructureInterface {
|
||||
|
||||
final static int NO_OFFSET = 1;
|
||||
|
||||
@IggyFieldType(value = DataType.wchar_t, count = 48)
|
||||
String name;
|
||||
|
||||
List<IggyFont> fonts = new ArrayList<>();
|
||||
// private List<Long> font_data_addresses = new ArrayList<>();
|
||||
List<IggyFont> add_fonts = new ArrayList<>();
|
||||
// private List<Long> add_font_data_addresses = new ArrayList<>();
|
||||
|
||||
private IggyFlashHeader64 hdr;
|
||||
|
||||
public IggySwf(ReadDataStreamInterface stream) throws IOException {
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
private List<IggyText> texts = new ArrayList<>();
|
||||
//private List<Long> text_data_addresses = new ArrayList<>();
|
||||
private List<IggyText> add_texts = new ArrayList<>();
|
||||
//private List<Long> add_text_data_addresses = new ArrayList<>();
|
||||
|
||||
//private byte font_add_data[];
|
||||
//private List<Long> font_additional_size = new ArrayList<>();
|
||||
private IggyFontBinInfo font_bin_info[];
|
||||
private List<String> sequenceNames = new ArrayList<>();
|
||||
//private List<Long> sequenceValues = new ArrayList<>();
|
||||
|
||||
private IggyFontTypeInfo type_info[];
|
||||
private String type_info_name[];
|
||||
private IggyDeclStrings decl_strings;
|
||||
private long ofs_additional;
|
||||
private long additional_address;
|
||||
|
||||
public IggyFlashHeader64 getHdr() {
|
||||
return hdr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface s) throws IOException {
|
||||
this.hdr = new IggyFlashHeader64(s);
|
||||
//Save all font bytes to buffer for later easy modification
|
||||
//here is offset[0] - 184
|
||||
name = s.readWChar();
|
||||
//here is offset[1] - 230
|
||||
int pad8 = 8 - (int) (s.position() % 8);
|
||||
if (pad8 > 8) {
|
||||
s.seek(pad8, SeekMode.CUR);
|
||||
}
|
||||
//here is offset [2] - 232
|
||||
s.seek(hdr.getBaseAddress(), SeekMode.SET);
|
||||
s.readUI64(); //pad 1
|
||||
|
||||
List<Long> itemsAddresses = new ArrayList<>();
|
||||
|
||||
while (true) {
|
||||
long offset = s.readUI64();
|
||||
if (offset == 1) {
|
||||
break;
|
||||
}
|
||||
itemsAddresses.add(offset + s.position() - 8);
|
||||
}
|
||||
if (hdr.getImported_guid() != 0) {
|
||||
ofs_additional = s.readUI64();
|
||||
additional_address = ofs_additional == 1 ? 0 : ofs_additional + s.position() - 8;
|
||||
}
|
||||
for (Long addr : itemsAddresses) {
|
||||
s.seek(addr, SeekMode.SET);
|
||||
int kind = s.readUI8();
|
||||
s.seek(-1, SeekMode.CUR);
|
||||
switch (kind) {
|
||||
case 22 /*FONT*/:
|
||||
IggyFont font = new IggyFont(s);
|
||||
//font_data_addresses.add(addr);
|
||||
fonts.add(font);
|
||||
break;
|
||||
case 6 /*TEXT*/:
|
||||
IggyText text = new IggyText(s);
|
||||
//text_data_addresses.add(addr);
|
||||
texts.add(text);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown item kind: " + kind);
|
||||
}
|
||||
}
|
||||
|
||||
if (additional_address != 0) {
|
||||
s.seek(additional_address, SeekMode.SET);
|
||||
List<Long> additionalItemsAddresses = new ArrayList<>();
|
||||
while (true) {
|
||||
long offset = s.readUI64();
|
||||
if (offset == 1) {
|
||||
break;
|
||||
}
|
||||
additionalItemsAddresses.add(offset + s.position() - 8);
|
||||
}
|
||||
for (Long addr : additionalItemsAddresses) {
|
||||
s.seek(addr, SeekMode.SET);
|
||||
int kind = s.readUI8();
|
||||
s.seek(-1, SeekMode.CUR);
|
||||
switch (kind) {
|
||||
case 22 /*FONT*/:
|
||||
IggyFont font = new IggyFont(s);
|
||||
//add_font_data_addresses.add(addr);
|
||||
add_fonts.add(font);
|
||||
break;
|
||||
case 6 /*TEXT*/:
|
||||
IggyText text = new IggyText(s);
|
||||
//add_text_data_addresses.add(addr);
|
||||
add_texts.add(text);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown imported item kind: " + kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
s.seek(hdr.getFontEndAddress(), SeekMode.SET);
|
||||
//here is offset [4] - 856 ?
|
||||
font_bin_info = new IggyFontBinInfo[(int) hdr.font_count];
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
font_bin_info[i] = new IggyFontBinInfo(s);
|
||||
}
|
||||
|
||||
sequenceNames = new ArrayList<>();
|
||||
|
||||
long seq_addresses[] = new long[]{hdr.getSequenceStartAddress1(), hdr.getSequenceStartAddress2(), hdr.getSequenceStartAddress3()};
|
||||
long seq_name_addresses[] = new long[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (seq_addresses[i] == 0) {
|
||||
seq_name_addresses[i] = 0;
|
||||
//0
|
||||
} else {
|
||||
s.seek(seq_addresses[i], SeekMode.SET);
|
||||
long ofs_seq_name = s.readUI64();
|
||||
seq_name_addresses[i] = ofs_seq_name == 1 ? 0 : ofs_seq_name + s.position() - 8;
|
||||
s.readUI64(); //is this crucial?
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (seq_name_addresses[i] > 0) {
|
||||
s.seek(seq_name_addresses[i], SeekMode.SET);
|
||||
sequenceNames.add(s.readWChar());
|
||||
} else {
|
||||
sequenceNames.add(null);
|
||||
}
|
||||
}
|
||||
s.pad8bytes();
|
||||
|
||||
//sequence = new IggySequence(s);
|
||||
s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
|
||||
type_info = new IggyFontTypeInfo[(int) hdr.font_count];
|
||||
type_info_name = new String[(int) hdr.font_count];
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
type_info[i] = new IggyFontTypeInfo(s);
|
||||
}
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
s.seek(type_info[i].getLocal_name_ofs_pos() + type_info[i].ofs_local_name, SeekMode.SET);
|
||||
type_info_name[i] = s.readWChar();
|
||||
}
|
||||
|
||||
s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
|
||||
decl_strings = new IggyDeclStrings(s);
|
||||
/*WriteDataStreamInterface outs = new TemporaryDataStream();
|
||||
writeToDataStream(outs);
|
||||
Helper.writeFile("d:\\Dropbox\\jpexs-laptop\\iggi\\parts\\swf_out.bin", outs.getAllBytes());*/
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
IggyIndexBuilder ib = s.getIndexing();
|
||||
hdr.writeToDataStream(s);
|
||||
s.writeWChar(name);
|
||||
s.pad8bytes();
|
||||
s.writeUI64(1);
|
||||
ib.write16bitArray(name.length() + 1);
|
||||
ib.writeTwoPaddingBytes();
|
||||
ib.write64bitPointerArray(64);
|
||||
long posBeforeOffsets = s.position();
|
||||
|
||||
final int FILL_LATER = 1;
|
||||
|
||||
List<Long> fontPosFillLater = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < fonts.size(); i++) {
|
||||
fontPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
List<Long> textPosFillLater = new ArrayList<>();
|
||||
for (int i = 0; i < texts.size(); i++) {
|
||||
textPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
s.writeUI64(1);
|
||||
|
||||
long addPosFillLater = s.position();
|
||||
s.writeUI64(FILL_LATER);
|
||||
long posAfter = posBeforeOffsets + 64 * 8;
|
||||
long curPos = s.position();
|
||||
long numLeft = posAfter - curPos;
|
||||
long ofsLeft = numLeft / 8;
|
||||
for (int i = 0; i < ofsLeft - 1; i++) {
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
|
||||
for (int i = 0; i < fonts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(fontPosFillLater.get(i));
|
||||
fonts.get(i).writeToDataStream(s);
|
||||
}
|
||||
for (int i = 0; i < texts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(textPosFillLater.get(i));
|
||||
texts.get(i).writeToDataStream(s);
|
||||
}
|
||||
|
||||
if (!add_fonts.isEmpty() || !add_texts.isEmpty()) {
|
||||
s.setOlderOffsetToThisPos(addPosFillLater);
|
||||
|
||||
List<Long> addFontPosFillLater = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < add_fonts.size(); i++) {
|
||||
addFontPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
List<Long> addTextPosFillLater = new ArrayList<>();
|
||||
for (int i = 0; i < add_texts.size(); i++) {
|
||||
addTextPosFillLater.add(s.position());
|
||||
s.writeUI64(FILL_LATER);
|
||||
}
|
||||
s.writeUI64(FILL_LATER);
|
||||
for (int i = 0; i < add_fonts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(addFontPosFillLater.get(i));
|
||||
add_fonts.get(i).writeToDataStream(s);
|
||||
}
|
||||
for (int i = 0; i < add_texts.size(); i++) {
|
||||
s.setOlderOffsetToThisPos(addTextPosFillLater.get(i));
|
||||
add_texts.get(i).writeToDataStream(s);
|
||||
}
|
||||
}
|
||||
s.setOlderOffsetToThisPos(hdr.getFont_end_ofs_pos());
|
||||
ib.writeConstLengthArray(IggyIndexBuilder.CONST_BIN_INFO_SIZE, hdr.font_count);
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
font_bin_info[i].writeToDataStream(s);
|
||||
}
|
||||
|
||||
long seq_ofs_pos[] = new long[]{hdr.getSequence_start1_ofs_pos(), hdr.getSequence_start2_ofs_pos(), hdr.getSequence_start3_ofs_pos()};
|
||||
long off_seq_expected[] = new long[]{hdr.off_sequence_start1, hdr.off_sequence_start2, hdr.off_sequence_start3};
|
||||
|
||||
long seq_name_fill_later[] = new long[3];
|
||||
|
||||
s.setOlderOffsetToThisPos(seq_ofs_pos[0]);
|
||||
s.writeUI64(1);
|
||||
s.writeUI64(1);
|
||||
ib.writeLengthCustom(16, new int[]{0}, new int[]{2});
|
||||
|
||||
seq_name_fill_later[2] = s.position();
|
||||
s.setOlderOffsetToThisPos(seq_ofs_pos[2]);
|
||||
s.writeUI64(FILL_LATER);
|
||||
s.writeUI64(0);
|
||||
ib.writeConstLength(IggyIndexBuilder.CONST_SEQUENCE_SIZE);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (sequenceNames.get(i) != null) {
|
||||
s.setOlderOffsetToThisPos(seq_name_fill_later[i]);
|
||||
ib.write16bitArray(sequenceNames.get(i).length() + 1);
|
||||
s.writeWChar(sequenceNames.get(i));
|
||||
}
|
||||
}
|
||||
s.setOlderOffsetToThisPos(hdr.getSequence_end_ofs_pos());
|
||||
s.pad8bytes();
|
||||
ib.pad8bytes();
|
||||
|
||||
ib.writeConstLengthArray(IggyIndexBuilder.CONST_TYPE_INFO_SIZE, hdr.font_count);
|
||||
s.setOlderOffsetToThisPos(hdr.getType_fonts_ofs_pos());
|
||||
//s.seek(hdr.getTypeFontsAddress(), SeekMode.SET);
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
type_info[i].writeToDataStream(s);
|
||||
}
|
||||
|
||||
for (int i = 0; i < hdr.font_count; i++) {
|
||||
ib.write16bitArray(type_info_name[i].length() + 1);
|
||||
s.setOlderOffsetToThisPos(type_info[i].getLocal_name_ofs_pos());
|
||||
s.writeWChar(type_info_name[i]);
|
||||
}
|
||||
s.pad8bytes();
|
||||
ib.pad8bytes();
|
||||
|
||||
s.setOlderOffsetToThisPos(hdr.getDecl_strings_ofs_pos());
|
||||
//s.seek(hdr.getDeclStringsAddress(), SeekMode.SET);
|
||||
decl_strings.writeToDataStream(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[\r\n");
|
||||
sb.append("name ").append(name).append("\r\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class IggyTag implements StructureInterface {
|
||||
|
||||
public abstract int getTagType();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("IggyTag (%04X)", getTagType());
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class IggyTag implements StructureInterface {
|
||||
|
||||
public abstract int getTagType();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("IggyTag (%04X)", getTagType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyText implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 104;
|
||||
|
||||
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
|
||||
long ofs_name;
|
||||
|
||||
@IggyArrayFieldType(value = DataType.wchar_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(ReadDataStreamInterface stream) throws IOException {
|
||||
this.readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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();
|
||||
|
||||
enum_hex = s.readUI16();
|
||||
fontIndex = s.readUI16(); //fontId
|
||||
zero = s.readUI32();
|
||||
one = s.readUI64(); //01CB FF33 3333
|
||||
some = s.readBytes(32); // [6] => 40, [24] => 8
|
||||
ofs_name = s.readUI64();
|
||||
long name_address = ofs_name + s.position() - 8;
|
||||
s.seek(name_address, SeekMode.SET);
|
||||
initialText = s.readWChar();
|
||||
s.pad8bytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_TEXT_DATA_SIZE);
|
||||
s.writeUI16(type);
|
||||
s.writeUI16(textIndex);
|
||||
s.writeBytes(zeroone);
|
||||
s.writeFloat(par1);
|
||||
s.writeFloat(par2);
|
||||
s.writeFloat(par3);
|
||||
s.writeFloat(par4);
|
||||
s.writeUI16(enum_hex);
|
||||
s.writeUI16(fontIndex);
|
||||
s.writeUI32(zero);
|
||||
s.writeUI64(one);
|
||||
s.writeBytes(some);
|
||||
s.writeUI64(ofs_name);
|
||||
long name_address = ofs_name + s.position() - 8;
|
||||
s.seek(name_address, SeekMode.SET);
|
||||
s.writeWChar(initialText);
|
||||
s.pad8bytes();
|
||||
|
||||
s.getIndexing().write16bitArray(initialText.length() + 1);
|
||||
s.getIndexing().pad8bytes();
|
||||
|
||||
}
|
||||
|
||||
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 com.jpexs.decompiler.flash.iggy.streams.IggyIndexBuilder;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.SeekMode;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.StructureInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyText implements StructureInterface {
|
||||
|
||||
public static final int STRUCT_SIZE = 104;
|
||||
|
||||
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
|
||||
long ofs_name;
|
||||
|
||||
@IggyArrayFieldType(value = DataType.wchar_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(ReadDataStreamInterface stream) throws IOException {
|
||||
this.readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface 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();
|
||||
|
||||
enum_hex = s.readUI16();
|
||||
fontIndex = s.readUI16(); //fontId
|
||||
zero = s.readUI32();
|
||||
one = s.readUI64(); //01CB FF33 3333
|
||||
some = s.readBytes(32); // [6] => 40, [24] => 8
|
||||
ofs_name = s.readUI64();
|
||||
long name_address = ofs_name + s.position() - 8;
|
||||
s.seek(name_address, SeekMode.SET);
|
||||
initialText = s.readWChar();
|
||||
s.pad8bytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface s) throws IOException {
|
||||
s.getIndexing().writeConstLength(IggyIndexBuilder.CONST_TEXT_DATA_SIZE);
|
||||
s.writeUI16(type);
|
||||
s.writeUI16(textIndex);
|
||||
s.writeBytes(zeroone);
|
||||
s.writeFloat(par1);
|
||||
s.writeFloat(par2);
|
||||
s.writeFloat(par3);
|
||||
s.writeFloat(par4);
|
||||
s.writeUI16(enum_hex);
|
||||
s.writeUI16(fontIndex);
|
||||
s.writeUI32(zero);
|
||||
s.writeUI64(one);
|
||||
s.writeBytes(some);
|
||||
s.writeUI64(ofs_name);
|
||||
long name_address = ofs_name + s.position() - 8;
|
||||
s.seek(name_address, SeekMode.SET);
|
||||
s.writeWChar(initialText);
|
||||
s.pad8bytes();
|
||||
|
||||
s.getIndexing().write16bitArray(initialText.length() + 1);
|
||||
s.getIndexing().pad8bytes();
|
||||
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getTextIndex() {
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
public byte[] getZeroone() {
|
||||
return zeroone;
|
||||
}
|
||||
|
||||
public float getPar1() {
|
||||
return par1;
|
||||
}
|
||||
|
||||
public float getPar2() {
|
||||
return par2;
|
||||
}
|
||||
|
||||
public float getPar3() {
|
||||
return par3;
|
||||
}
|
||||
|
||||
public float getPar4() {
|
||||
return par4;
|
||||
}
|
||||
|
||||
public int getEnum_hex() {
|
||||
return enum_hex;
|
||||
}
|
||||
|
||||
public int getFontIndex() {
|
||||
return fontIndex;
|
||||
}
|
||||
|
||||
public long getZero() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
public long getOne() {
|
||||
return one;
|
||||
}
|
||||
|
||||
public byte[] getSome() {
|
||||
return some;
|
||||
}
|
||||
|
||||
public String getInitialText() {
|
||||
return initialText;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RawIggyPart extends IggyTag {
|
||||
|
||||
byte[] rawData;
|
||||
int tagType;
|
||||
private int length;
|
||||
|
||||
public RawIggyPart(int tagType, ReadDataStreamInterface stream, int length) throws IOException {
|
||||
this.length = length;
|
||||
this.tagType = tagType;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTagType() {
|
||||
return tagType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
rawData = stream.readBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
stream.writeBytes(rawData);
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.ReadDataStreamInterface;
|
||||
import com.jpexs.decompiler.flash.iggy.streams.WriteDataStreamInterface;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RawIggyPart extends IggyTag {
|
||||
|
||||
byte[] rawData;
|
||||
int tagType;
|
||||
private int length;
|
||||
|
||||
public RawIggyPart(int tagType, ReadDataStreamInterface stream, int length) throws IOException {
|
||||
this.length = length;
|
||||
this.tagType = tagType;
|
||||
readFromDataStream(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTagType() {
|
||||
return tagType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException {
|
||||
rawData = stream.readBytes(length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException {
|
||||
stream.writeBytes(rawData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,80 +1,80 @@
|
||||
package com.jpexs.decompiler.flash.iggy.annotations;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FieldPrinter {
|
||||
|
||||
public static String getObjectSummary(Object val) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("/---" + val.getClass().getSimpleName() + "---\r\n");
|
||||
for (Field f : val.getClass().getDeclaredFields()) {
|
||||
sb.append(f.getName()).append(": ");
|
||||
IggyFieldType an = f.getAnnotation(IggyFieldType.class);
|
||||
if (an != null) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
switch (an.value()) {
|
||||
case float_t:
|
||||
sb.append(f.getFloat(val));
|
||||
break;
|
||||
case uint8_t:
|
||||
case uint16_t:
|
||||
sb.append(f.getInt(val));
|
||||
break;
|
||||
case uint32_t:
|
||||
case uint64_t:
|
||||
sb.append(f.getLong(val));
|
||||
break;
|
||||
case wchar_t:
|
||||
sb.append("\"").append(f.get(val)).append("\"");
|
||||
break;
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
sb.append("\r\n");
|
||||
}
|
||||
sb.append("---/");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String getObjectWriteTo(Class<?> cls) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Field f : cls.getDeclaredFields()) {
|
||||
sb.append("stream.write");
|
||||
IggyFieldType an = f.getAnnotation(IggyFieldType.class);
|
||||
if (an != null) {
|
||||
switch (an.value()) {
|
||||
case float_t:
|
||||
sb.append("Float");
|
||||
break;
|
||||
case uint8_t:
|
||||
sb.append("UI8");
|
||||
break;
|
||||
case uint16_t:
|
||||
sb.append("UI16");
|
||||
break;
|
||||
case uint32_t:
|
||||
sb.append("UI32");
|
||||
break;
|
||||
case uint64_t:
|
||||
sb.append("UI64");
|
||||
break;
|
||||
case wchar_t:
|
||||
sb.append("//FIXME");
|
||||
break;
|
||||
}
|
||||
sb.append("(").append(f.getName()).append(");\r\n");
|
||||
if (an.count() > 0) {
|
||||
sb.append("//FIXME count");
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.annotations;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FieldPrinter {
|
||||
|
||||
public static String getObjectSummary(Object val) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("/---" + val.getClass().getSimpleName() + "---\r\n");
|
||||
for (Field f : val.getClass().getDeclaredFields()) {
|
||||
sb.append(f.getName()).append(": ");
|
||||
IggyFieldType an = f.getAnnotation(IggyFieldType.class);
|
||||
if (an != null) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
switch (an.value()) {
|
||||
case float_t:
|
||||
sb.append(f.getFloat(val));
|
||||
break;
|
||||
case uint8_t:
|
||||
case uint16_t:
|
||||
sb.append(f.getInt(val));
|
||||
break;
|
||||
case uint32_t:
|
||||
case uint64_t:
|
||||
sb.append(f.getLong(val));
|
||||
break;
|
||||
case wchar_t:
|
||||
sb.append("\"").append(f.get(val)).append("\"");
|
||||
break;
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
sb.append("\r\n");
|
||||
}
|
||||
sb.append("---/");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String getObjectWriteTo(Class<?> cls) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Field f : cls.getDeclaredFields()) {
|
||||
sb.append("stream.write");
|
||||
IggyFieldType an = f.getAnnotation(IggyFieldType.class);
|
||||
if (an != null) {
|
||||
switch (an.value()) {
|
||||
case float_t:
|
||||
sb.append("Float");
|
||||
break;
|
||||
case uint8_t:
|
||||
sb.append("UI8");
|
||||
break;
|
||||
case uint16_t:
|
||||
sb.append("UI16");
|
||||
break;
|
||||
case uint32_t:
|
||||
sb.append("UI32");
|
||||
break;
|
||||
case uint64_t:
|
||||
sb.append("UI64");
|
||||
break;
|
||||
case wchar_t:
|
||||
sb.append("//FIXME");
|
||||
break;
|
||||
}
|
||||
sb.append("(").append(f.getName()).append(");\r\n");
|
||||
if (an.count() > 0) {
|
||||
sb.append("//FIXME count");
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.getTargetX());
|
||||
prevY = scr.moveDeltaY = makeLengthsEmY(ign.getTargetY());
|
||||
scr.fillStyles = new FILLSTYLEARRAY();
|
||||
scr.lineStyles = new LINESTYLEARRAY();
|
||||
scr.calculateBits();
|
||||
retList.add(scr);
|
||||
} else {
|
||||
|
||||
int curX1 = makeLengthsEmX(ign.getTargetX());
|
||||
int curY1 = makeLengthsEmY(ign.getTargetY());
|
||||
|
||||
int curX2 = makeLengthsEmX(ign.getControlX());
|
||||
int curY2 = makeLengthsEmY(ign.getControlY());
|
||||
|
||||
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.getTargetX());
|
||||
prevY = scr.moveDeltaY = makeLengthsEmY(ign.getTargetY());
|
||||
scr.fillStyles = new FILLSTYLEARRAY();
|
||||
scr.lineStyles = new LINESTYLEARRAY();
|
||||
scr.calculateBits();
|
||||
retList.add(scr);
|
||||
} else {
|
||||
|
||||
int curX1 = makeLengthsEmX(ign.getTargetX());
|
||||
int curY1 = makeLengthsEmY(ign.getTargetY());
|
||||
|
||||
int curX2 = makeLengthsEmX(ign.getControlX());
|
||||
int curY2 = makeLengthsEmY(ign.getControlY());
|
||||
|
||||
if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_LINE_TO) {
|
||||
StraightEdgeRecord ser = new StraightEdgeRecord();
|
||||
ser.deltaX = curX1 - prevX;
|
||||
ser.deltaY = curY1 - prevY;
|
||||
ser.generalLineFlag = true;
|
||||
ser.simplify();
|
||||
ser.calculateBits();
|
||||
prevX = curX1;
|
||||
prevY = curY1;
|
||||
retList.add(ser);
|
||||
} else if (ign.getNodeType() == IggyShapeNode.NODE_TYPE_CURVE_POINT) {
|
||||
CurvedEdgeRecord cer = new CurvedEdgeRecord();
|
||||
cer.controlDeltaX = curX2 - prevX;
|
||||
cer.controlDeltaY = curY2 - prevY;
|
||||
cer.anchorDeltaX = curX1 - curX2;
|
||||
cer.anchorDeltaY = curY1 - curY2;
|
||||
prevX = curX1;
|
||||
prevY = curY1;
|
||||
cer.calculateBits();
|
||||
retList.add(cer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!retList.isEmpty()) {
|
||||
StyleChangeRecord init;
|
||||
if (retList.get(0) instanceof StyleChangeRecord) {
|
||||
init = (StyleChangeRecord) retList.get(0);
|
||||
} else {
|
||||
init = new StyleChangeRecord();
|
||||
retList.add(0, init);
|
||||
}
|
||||
init.stateFillStyle0 = true;
|
||||
init.fillStyle0 = 1;
|
||||
shape.numFillBits = 1;
|
||||
|
||||
} else {
|
||||
shape.numFillBits = 0;
|
||||
|
||||
}
|
||||
retList.add(new EndShapeRecord());
|
||||
shape.shapeRecords = retList;
|
||||
shape.numLineBits = 0;
|
||||
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,134 +1,134 @@
|
||||
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.decompiler.flash.iggy.IggyFont;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
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.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @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 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys() {
|
||||
Set<String> ret = new TreeSet<>();
|
||||
for (int i = 0; i < length(); i++) {
|
||||
ret.add(iggyFile.getSwfName());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int keyToSwfIndex(String key) {
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (key.equals(iggyFile.getSwfName())) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Key " + key + " does not exist!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeekableInputStream getSWF(String key) throws IOException {
|
||||
SWF swf = IggyToSwfConvertor.getSwf(iggyFile);
|
||||
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 false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putSWF(String key, InputStream is) throws IOException {
|
||||
try {
|
||||
int swfIndex = 0;
|
||||
SWF swf = new SWF(is, false, false);
|
||||
List<DefineFont2Tag> fontTags = new ArrayList<>();
|
||||
for (CharacterTag ct : swf.getCharacters().values()) {
|
||||
if (ct instanceof DefineFont2Tag) {
|
||||
fontTags.add((DefineFont2Tag) ct);
|
||||
}
|
||||
}
|
||||
int fontCount = iggyFile.getFontCount();
|
||||
if (fontCount != fontTags.size()) {
|
||||
throw new IOException("Font count is different from original iggy file");
|
||||
}
|
||||
for (int i = 0; i < fontCount; i++) {
|
||||
IggyFont iggyFont = iggyFile.getFont(i);
|
||||
DefineFont2Tag fontTag = fontTags.get(i);
|
||||
SwfToIggyConvertor.updateIggyFont(iggyFont, fontTag);
|
||||
}
|
||||
iggyFile.saveChanges();
|
||||
return true;
|
||||
} catch (InterruptedException ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
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.decompiler.flash.iggy.IggyFont;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
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.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @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 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeys() {
|
||||
Set<String> ret = new TreeSet<>();
|
||||
for (int i = 0; i < length(); i++) {
|
||||
ret.add(iggyFile.getSwfName());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int keyToSwfIndex(String key) {
|
||||
for (int i = 0; i < length(); i++) {
|
||||
if (key.equals(iggyFile.getSwfName())) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Key " + key + " does not exist!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeekableInputStream getSWF(String key) throws IOException {
|
||||
SWF swf = IggyToSwfConvertor.getSwf(iggyFile);
|
||||
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 false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putSWF(String key, InputStream is) throws IOException {
|
||||
try {
|
||||
int swfIndex = 0;
|
||||
SWF swf = new SWF(is, false, false);
|
||||
List<DefineFont2Tag> fontTags = new ArrayList<>();
|
||||
for (CharacterTag ct : swf.getCharacters().values()) {
|
||||
if (ct instanceof DefineFont2Tag) {
|
||||
fontTags.add((DefineFont2Tag) ct);
|
||||
}
|
||||
}
|
||||
int fontCount = iggyFile.getFontCount();
|
||||
if (fontCount != fontTags.size()) {
|
||||
throw new IOException("Font count is different from original iggy file");
|
||||
}
|
||||
for (int i = 0; i < fontCount; i++) {
|
||||
IggyFont iggyFont = iggyFile.getFont(i);
|
||||
DefineFont2Tag fontTag = fontTags.get(i);
|
||||
SwfToIggyConvertor.updateIggyFont(iggyFont, fontTag);
|
||||
}
|
||||
iggyFile.saveChanges();
|
||||
return true;
|
||||
} catch (InterruptedException ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,244 +1,244 @@
|
||||
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.IggySwf;
|
||||
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 void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
|
||||
exportSwfToDir(file, outputDir);
|
||||
}
|
||||
|
||||
public static void exportSwfToDir(IggyFile file, File outputDir) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName()))) {
|
||||
exportSwf(file, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwfToFile(IggyFile file, File outputFile) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
|
||||
exportSwf(file, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwf(IggyFile file, OutputStream output) throws IOException {
|
||||
SWF swf = getSwf(file);
|
||||
swf.saveTo(output);
|
||||
}
|
||||
|
||||
private static int makeLengthsEm(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
public static SWF getSwf(IggyFile file) {
|
||||
SWF swf = new SWF();
|
||||
swf.compression = SWFCompression.NONE;
|
||||
swf.frameCount = 1; //FIXME!!
|
||||
swf.frameRate = file.getSwfFrameRate();
|
||||
swf.gfx = false;
|
||||
swf.displayRect = new RECT(
|
||||
(int) (file.getSwfXMin() * SWF.unitDivisor),
|
||||
(int) (file.getSwfXMax() * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMin() * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMax() * 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 fontCount = file.getFontCount();
|
||||
|
||||
int currentCharId = 0;
|
||||
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
|
||||
|
||||
for (int fontIndex = 0; fontIndex < fontCount; fontIndex++) {
|
||||
IggyFont iggyFont = file.getFont(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);
|
||||
fontTag.codeTable.add(code);
|
||||
IggyShape glyph = iggyFont.getChars().get(i);
|
||||
SHAPE shp;
|
||||
if (glyph != null) {
|
||||
shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
|
||||
fontTag.fontBoundsTable.add(shp.getBounds());
|
||||
} else {
|
||||
shp = new SHAPE();
|
||||
shp.shapeRecords = new ArrayList<>();
|
||||
shp.shapeRecords.add(new EndShapeRecord());
|
||||
fontTag.fontBoundsTable.add(new RECT()); //??
|
||||
}
|
||||
fontTag.glyphShapeTable.add(shp);
|
||||
|
||||
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.IggySwf;
|
||||
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 void exportAllSwfsToDir(IggyFile file, File outputDir) throws IOException {
|
||||
exportSwfToDir(file, outputDir);
|
||||
}
|
||||
|
||||
public static void exportSwfToDir(IggyFile file, File outputDir) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(new File(outputDir, file.getSwfName()))) {
|
||||
exportSwf(file, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwfToFile(IggyFile file, File outputFile) throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
|
||||
exportSwf(file, fos);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exportSwf(IggyFile file, OutputStream output) throws IOException {
|
||||
SWF swf = getSwf(file);
|
||||
swf.saveTo(output);
|
||||
}
|
||||
|
||||
private static int makeLengthsEm(double val) {
|
||||
return (int) (val * 1024.0);
|
||||
}
|
||||
|
||||
public static SWF getSwf(IggyFile file) {
|
||||
SWF swf = new SWF();
|
||||
swf.compression = SWFCompression.NONE;
|
||||
swf.frameCount = 1; //FIXME!!
|
||||
swf.frameRate = file.getSwfFrameRate();
|
||||
swf.gfx = false;
|
||||
swf.displayRect = new RECT(
|
||||
(int) (file.getSwfXMin() * SWF.unitDivisor),
|
||||
(int) (file.getSwfXMax() * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMin() * SWF.unitDivisor),
|
||||
(int) (file.getSwfYMax() * 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 fontCount = file.getFontCount();
|
||||
|
||||
int currentCharId = 0;
|
||||
Map<Integer, Integer> fontIndex2CharId = new HashMap<>();
|
||||
|
||||
for (int fontIndex = 0; fontIndex < fontCount; fontIndex++) {
|
||||
IggyFont iggyFont = file.getFont(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);
|
||||
fontTag.codeTable.add(code);
|
||||
IggyShape glyph = iggyFont.getChars().get(i);
|
||||
SHAPE shp;
|
||||
if (glyph != null) {
|
||||
shp = IggyShapeToSwfConvertor.convertCharToShape(glyph);
|
||||
fontTag.fontBoundsTable.add(shp.getBounds());
|
||||
} else {
|
||||
shp = new SHAPE();
|
||||
shp.shapeRecords = new ArrayList<>();
|
||||
shp.shapeRecords.add(new EndShapeRecord());
|
||||
fontTag.fontBoundsTable.add(new RECT()); //??
|
||||
}
|
||||
fontTag.glyphShapeTable.add(shp);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
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.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SwfShapeToIggyConvertor {
|
||||
|
||||
private static float normalizeLengths(int val) {
|
||||
return (val / 1024f);
|
||||
}
|
||||
|
||||
public static IggyShape convertShape(SHAPE swfShape) {
|
||||
/*if (swfShape.shapeRecords.size() == 1) { //no glyphs, maybe space
|
||||
return null;
|
||||
}*/
|
||||
List<IggyShapeNode> nodes = new ArrayList<>();
|
||||
RECT bounds = swfShape.getBounds();
|
||||
boolean first = true;
|
||||
float curX = 0f;
|
||||
float curY = 0f;
|
||||
for (SHAPERECORD rec : swfShape.shapeRecords) {
|
||||
if (rec instanceof StraightEdgeRecord) {
|
||||
StraightEdgeRecord ser = (StraightEdgeRecord) rec;
|
||||
curX += normalizeLengths(ser.deltaX);
|
||||
curY += normalizeLengths(ser.deltaY);
|
||||
nodes.add(new IggyShapeNode(curX, curY, 0f, 0f, IggyShapeNode.NODE_TYPE_LINE_TO, 0, first));
|
||||
} else if (rec instanceof CurvedEdgeRecord) {
|
||||
CurvedEdgeRecord cer = (CurvedEdgeRecord) rec;
|
||||
float controlX = curX + normalizeLengths(cer.controlDeltaX);
|
||||
float controlY = curY + normalizeLengths(cer.controlDeltaY);
|
||||
curX = curX + normalizeLengths(cer.controlDeltaX + cer.anchorDeltaX);
|
||||
curY = curY + normalizeLengths(cer.controlDeltaY + cer.anchorDeltaY);
|
||||
nodes.add(new IggyShapeNode(curX, curY, controlX, controlY, IggyShapeNode.NODE_TYPE_CURVE_POINT, 0, first));
|
||||
} else if (rec instanceof StyleChangeRecord) {
|
||||
StyleChangeRecord scr = (StyleChangeRecord) rec;
|
||||
if (scr.stateMoveTo) {
|
||||
curX = normalizeLengths(scr.moveDeltaX);
|
||||
curY = normalizeLengths(scr.moveDeltaY);
|
||||
nodes.add(new IggyShapeNode(curX, curY, 0f, 0f, IggyShapeNode.NODE_TYPE_MOVE, 0, first));
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
IggyShape ret = new IggyShape(normalizeLengths(bounds.Xmin), normalizeLengths(bounds.Ymin), normalizeLengths(bounds.Xmax), normalizeLengths(bounds.Ymax), nodes);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
|
||||
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.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SwfShapeToIggyConvertor {
|
||||
|
||||
private static float normalizeLengths(int val) {
|
||||
return (val / 1024f);
|
||||
}
|
||||
|
||||
public static IggyShape convertShape(SHAPE swfShape) {
|
||||
/*if (swfShape.shapeRecords.size() == 1) { //no glyphs, maybe space
|
||||
return null;
|
||||
}*/
|
||||
List<IggyShapeNode> nodes = new ArrayList<>();
|
||||
RECT bounds = swfShape.getBounds();
|
||||
boolean first = true;
|
||||
float curX = 0f;
|
||||
float curY = 0f;
|
||||
for (SHAPERECORD rec : swfShape.shapeRecords) {
|
||||
if (rec instanceof StraightEdgeRecord) {
|
||||
StraightEdgeRecord ser = (StraightEdgeRecord) rec;
|
||||
curX += normalizeLengths(ser.deltaX);
|
||||
curY += normalizeLengths(ser.deltaY);
|
||||
nodes.add(new IggyShapeNode(curX, curY, 0f, 0f, IggyShapeNode.NODE_TYPE_LINE_TO, 0, first));
|
||||
} else if (rec instanceof CurvedEdgeRecord) {
|
||||
CurvedEdgeRecord cer = (CurvedEdgeRecord) rec;
|
||||
float controlX = curX + normalizeLengths(cer.controlDeltaX);
|
||||
float controlY = curY + normalizeLengths(cer.controlDeltaY);
|
||||
curX = curX + normalizeLengths(cer.controlDeltaX + cer.anchorDeltaX);
|
||||
curY = curY + normalizeLengths(cer.controlDeltaY + cer.anchorDeltaY);
|
||||
nodes.add(new IggyShapeNode(curX, curY, controlX, controlY, IggyShapeNode.NODE_TYPE_CURVE_POINT, 0, first));
|
||||
} else if (rec instanceof StyleChangeRecord) {
|
||||
StyleChangeRecord scr = (StyleChangeRecord) rec;
|
||||
if (scr.stateMoveTo) {
|
||||
curX = normalizeLengths(scr.moveDeltaX);
|
||||
curY = normalizeLengths(scr.moveDeltaY);
|
||||
nodes.add(new IggyShapeNode(curX, curY, 0f, 0f, IggyShapeNode.NODE_TYPE_MOVE, 0, first));
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
IggyShape ret = new IggyShape(normalizeLengths(bounds.Xmin), normalizeLengths(bounds.Ymin), normalizeLengths(bounds.Xmax), normalizeLengths(bounds.Ymax), nodes);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,157 +1,157 @@
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharIndices;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFont;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SwfToIggyConvertor {
|
||||
|
||||
private static float normalizeLengths(int val) {
|
||||
return (val / 1024f);
|
||||
}
|
||||
|
||||
public static void updateIggyFont(IggyFont iggyFont, DefineFont2Tag fontTag) {
|
||||
/*byte zeroone[] = new byte[28];
|
||||
zeroone[12] = 1;
|
||||
long flags = 65795;
|
||||
float unk_float[] = new float[]{
|
||||
-0.6484375f,
|
||||
-1.116211f,
|
||||
1.116211f,
|
||||
0.6679688f,
|
||||
0f
|
||||
};
|
||||
int xscale = 80;
|
||||
int yscale = 28;
|
||||
float ssr1 = 0.9f;
|
||||
float ssr2 = 0.3f;
|
||||
long what_2 = 33188160;
|
||||
long what_3 = 33600216;
|
||||
byte zeroes48a[] = new byte[48];
|
||||
byte zeroes48b[] = new byte[48];
|
||||
float sss1 = 1.1728859f;
|
||||
float sss2 = 1.1728706f;
|
||||
float sss3 = 1.1728821f;
|
||||
float sss4 = 1.1729145f;*/
|
||||
List<IggyCharOffset> charOffsets = new ArrayList<>();
|
||||
|
||||
List<IggyShape> glyphs = new ArrayList<>();
|
||||
|
||||
for (SHAPE s : fontTag.glyphShapeTable) {
|
||||
glyphs.add(SwfShapeToIggyConvertor.convertShape(s));
|
||||
}
|
||||
|
||||
List<Character> chars = new ArrayList<>();
|
||||
for (int code : fontTag.codeTable) {
|
||||
chars.add((char) code);
|
||||
}
|
||||
IggyCharIndices codePoints = new IggyCharIndices(chars);
|
||||
List<Float> scales = new ArrayList<>();
|
||||
for (int adv : fontTag.fontAdvanceTable) {
|
||||
scales.add(normalizeLengths(adv));
|
||||
}
|
||||
IggyCharAdvances charScales = new IggyCharAdvances(scales);
|
||||
List<Character> charA = new ArrayList<>();
|
||||
List<Character> charB = new ArrayList<>();
|
||||
List<Short> kernOffs = new ArrayList<>();
|
||||
|
||||
//IggyCharOffset
|
||||
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
|
||||
charA.add((char) rec.fontKerningCode1);
|
||||
charB.add((char) rec.fontKerningCode2);
|
||||
kernOffs.add((short) rec.fontKerningAdjustment);
|
||||
}
|
||||
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
|
||||
|
||||
for (int i = 0; i < fontTag.getCharacterCount(); i++) {
|
||||
charOffsets.add(new IggyCharOffset(1, 0, 80, 19)); //XSCALE, YSCALE???
|
||||
}
|
||||
|
||||
iggyFont.setCharCount(fontTag.getCharacterCount());
|
||||
iggyFont.setCharCount2(fontTag.getCharacterCount());
|
||||
iggyFont.setAscent(fontTag.getAscent());
|
||||
iggyFont.setDescent(fontTag.getDescent());
|
||||
iggyFont.setLeading(fontTag.getLeading());
|
||||
iggyFont.setName(fontTag.getFontName());
|
||||
iggyFont.setCharOffsets(charOffsets);
|
||||
iggyFont.setGlyphs(glyphs);
|
||||
iggyFont.setCodePoints(codePoints);
|
||||
iggyFont.setCharScales(charScales);
|
||||
iggyFont.setCharKernings(charKernings);
|
||||
/*
|
||||
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
|
||||
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
|
||||
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
|
||||
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
|
||||
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
|
||||
charOffsets, glyphs, codePoints, charScales, charKernings);
|
||||
*/
|
||||
}
|
||||
|
||||
public static IggyFont createIggyFont(DefineFont2Tag fontTag) {
|
||||
byte zeroone[] = new byte[28];
|
||||
zeroone[12] = 1;
|
||||
long flags = 65795;
|
||||
float unk_float[] = new float[]{
|
||||
-0.6484375f,
|
||||
-1.116211f,
|
||||
1.116211f,
|
||||
0.6679688f,
|
||||
0f
|
||||
};
|
||||
int xscale = 80;
|
||||
int yscale = 28;
|
||||
float ssr1 = 0.9f;
|
||||
float ssr2 = 0.3f;
|
||||
long what_2 = 33188160;
|
||||
long what_3 = 33600216;
|
||||
byte zeroes48a[] = new byte[48];
|
||||
byte zeroes48b[] = new byte[48];
|
||||
float sss1 = 1.1728859f;
|
||||
float sss2 = 1.1728706f;
|
||||
float sss3 = 1.1728821f;
|
||||
float sss4 = 1.1729145f;
|
||||
List<IggyCharOffset> charOffsets = new ArrayList<>();
|
||||
List<IggyShape> glyphs = new ArrayList<>();
|
||||
List<Character> chars = new ArrayList<>();
|
||||
for (int code : fontTag.codeTable) {
|
||||
chars.add((char) code);
|
||||
}
|
||||
IggyCharIndices codePoints = new IggyCharIndices(chars);
|
||||
List<Float> scales = new ArrayList<>();
|
||||
for (int adv : fontTag.fontAdvanceTable) {
|
||||
scales.add((float) adv);
|
||||
}
|
||||
IggyCharAdvances charScales = new IggyCharAdvances(scales);
|
||||
List<Character> charA = new ArrayList<>();
|
||||
List<Character> charB = new ArrayList<>();
|
||||
List<Short> kernOffs = new ArrayList<>();
|
||||
|
||||
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
|
||||
charA.add((char) rec.fontKerningCode1);
|
||||
charB.add((char) rec.fontKerningCode2);
|
||||
kernOffs.add((short) rec.fontKerningAdjustment);
|
||||
}
|
||||
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
|
||||
|
||||
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
|
||||
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
|
||||
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
|
||||
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
|
||||
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
|
||||
charOffsets, glyphs, codePoints, charScales, charKernings);
|
||||
return iggyFont;
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.conversion;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharAdvances;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharIndices;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFont;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.tags.DefineFont2Tag;
|
||||
import com.jpexs.decompiler.flash.types.KERNINGRECORD;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class SwfToIggyConvertor {
|
||||
|
||||
private static float normalizeLengths(int val) {
|
||||
return (val / 1024f);
|
||||
}
|
||||
|
||||
public static void updateIggyFont(IggyFont iggyFont, DefineFont2Tag fontTag) {
|
||||
/*byte zeroone[] = new byte[28];
|
||||
zeroone[12] = 1;
|
||||
long flags = 65795;
|
||||
float unk_float[] = new float[]{
|
||||
-0.6484375f,
|
||||
-1.116211f,
|
||||
1.116211f,
|
||||
0.6679688f,
|
||||
0f
|
||||
};
|
||||
int xscale = 80;
|
||||
int yscale = 28;
|
||||
float ssr1 = 0.9f;
|
||||
float ssr2 = 0.3f;
|
||||
long what_2 = 33188160;
|
||||
long what_3 = 33600216;
|
||||
byte zeroes48a[] = new byte[48];
|
||||
byte zeroes48b[] = new byte[48];
|
||||
float sss1 = 1.1728859f;
|
||||
float sss2 = 1.1728706f;
|
||||
float sss3 = 1.1728821f;
|
||||
float sss4 = 1.1729145f;*/
|
||||
List<IggyCharOffset> charOffsets = new ArrayList<>();
|
||||
|
||||
List<IggyShape> glyphs = new ArrayList<>();
|
||||
|
||||
for (SHAPE s : fontTag.glyphShapeTable) {
|
||||
glyphs.add(SwfShapeToIggyConvertor.convertShape(s));
|
||||
}
|
||||
|
||||
List<Character> chars = new ArrayList<>();
|
||||
for (int code : fontTag.codeTable) {
|
||||
chars.add((char) code);
|
||||
}
|
||||
IggyCharIndices codePoints = new IggyCharIndices(chars);
|
||||
List<Float> scales = new ArrayList<>();
|
||||
for (int adv : fontTag.fontAdvanceTable) {
|
||||
scales.add(normalizeLengths(adv));
|
||||
}
|
||||
IggyCharAdvances charScales = new IggyCharAdvances(scales);
|
||||
List<Character> charA = new ArrayList<>();
|
||||
List<Character> charB = new ArrayList<>();
|
||||
List<Short> kernOffs = new ArrayList<>();
|
||||
|
||||
//IggyCharOffset
|
||||
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
|
||||
charA.add((char) rec.fontKerningCode1);
|
||||
charB.add((char) rec.fontKerningCode2);
|
||||
kernOffs.add((short) rec.fontKerningAdjustment);
|
||||
}
|
||||
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
|
||||
|
||||
for (int i = 0; i < fontTag.getCharacterCount(); i++) {
|
||||
charOffsets.add(new IggyCharOffset(1, 0, 80, 19)); //XSCALE, YSCALE???
|
||||
}
|
||||
|
||||
iggyFont.setCharCount(fontTag.getCharacterCount());
|
||||
iggyFont.setCharCount2(fontTag.getCharacterCount());
|
||||
iggyFont.setAscent(fontTag.getAscent());
|
||||
iggyFont.setDescent(fontTag.getDescent());
|
||||
iggyFont.setLeading(fontTag.getLeading());
|
||||
iggyFont.setName(fontTag.getFontName());
|
||||
iggyFont.setCharOffsets(charOffsets);
|
||||
iggyFont.setGlyphs(glyphs);
|
||||
iggyFont.setCodePoints(codePoints);
|
||||
iggyFont.setCharScales(charScales);
|
||||
iggyFont.setCharKernings(charKernings);
|
||||
/*
|
||||
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
|
||||
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
|
||||
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
|
||||
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
|
||||
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
|
||||
charOffsets, glyphs, codePoints, charScales, charKernings);
|
||||
*/
|
||||
}
|
||||
|
||||
public static IggyFont createIggyFont(DefineFont2Tag fontTag) {
|
||||
byte zeroone[] = new byte[28];
|
||||
zeroone[12] = 1;
|
||||
long flags = 65795;
|
||||
float unk_float[] = new float[]{
|
||||
-0.6484375f,
|
||||
-1.116211f,
|
||||
1.116211f,
|
||||
0.6679688f,
|
||||
0f
|
||||
};
|
||||
int xscale = 80;
|
||||
int yscale = 28;
|
||||
float ssr1 = 0.9f;
|
||||
float ssr2 = 0.3f;
|
||||
long what_2 = 33188160;
|
||||
long what_3 = 33600216;
|
||||
byte zeroes48a[] = new byte[48];
|
||||
byte zeroes48b[] = new byte[48];
|
||||
float sss1 = 1.1728859f;
|
||||
float sss2 = 1.1728706f;
|
||||
float sss3 = 1.1728821f;
|
||||
float sss4 = 1.1729145f;
|
||||
List<IggyCharOffset> charOffsets = new ArrayList<>();
|
||||
List<IggyShape> glyphs = new ArrayList<>();
|
||||
List<Character> chars = new ArrayList<>();
|
||||
for (int code : fontTag.codeTable) {
|
||||
chars.add((char) code);
|
||||
}
|
||||
IggyCharIndices codePoints = new IggyCharIndices(chars);
|
||||
List<Float> scales = new ArrayList<>();
|
||||
for (int adv : fontTag.fontAdvanceTable) {
|
||||
scales.add((float) adv);
|
||||
}
|
||||
IggyCharAdvances charScales = new IggyCharAdvances(scales);
|
||||
List<Character> charA = new ArrayList<>();
|
||||
List<Character> charB = new ArrayList<>();
|
||||
List<Short> kernOffs = new ArrayList<>();
|
||||
|
||||
for (KERNINGRECORD rec : fontTag.fontKerningTable) {
|
||||
charA.add((char) rec.fontKerningCode1);
|
||||
charB.add((char) rec.fontKerningCode2);
|
||||
kernOffs.add((short) rec.fontKerningAdjustment);
|
||||
}
|
||||
IggyCharKerning charKernings = new IggyCharKerning(charA, charB, kernOffs);
|
||||
|
||||
IggyFont iggyFont = new IggyFont(IggyFont.ID, 0, zeroone, fontTag.getCharacterCount(),
|
||||
fontTag.getAscent(), fontTag.getDescent(), fontTag.getLeading(), flags,
|
||||
fontTag.fontKerningTable.size(), unk_float, 0, what_2, 0, 1,
|
||||
xscale, yscale, 0, ssr1, ssr2, fontTag.getCharacterCount(), 0, what_3, zeroes48a, zeroes48b,
|
||||
sss1, 1, sss2, 1, sss3, 1, sss4, 1, fontTag.getFontName(),
|
||||
charOffsets, glyphs, codePoints, charScales, charKernings);
|
||||
return iggyFont;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,241 +1,241 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class AbstractDataStream implements DataStreamInterface {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
@Override
|
||||
public abstract Long available();
|
||||
|
||||
@Override
|
||||
public abstract long position();
|
||||
|
||||
@Override
|
||||
public long readUI64() throws IOException {
|
||||
long lsb = readUI32();
|
||||
long msb = readUI32();
|
||||
long result = msb << 32 | lsb;
|
||||
return result & 0xffffffffffffffffL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readSI64() throws IOException {
|
||||
long lsb = readUI32();
|
||||
long msb = readUI32();
|
||||
return msb << 32 | lsb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeSI64(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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readUI32() throws IOException {
|
||||
try {
|
||||
return (readUI8() | (readUI8() << 8) | (readUI8() << 16) | (readUI8() << 24));
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUI16() throws IOException {
|
||||
try {
|
||||
return (readUI8() | (readUI8() << 8)) & 0xffff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeUI16(int val) throws IOException {
|
||||
write(val & 0xff);
|
||||
write((val >> 8) & 0xff);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUI8() throws IOException {
|
||||
try {
|
||||
return read() & 0xff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeUI8(int val) throws IOException {
|
||||
write(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat((int) readUI32());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeFloat(float val) throws IOException {
|
||||
return writeUI32(Float.floatToIntBits(val));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readBytes(int numBytes) throws IOException {
|
||||
byte[] ret = new byte[numBytes];
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public byte[] getAllBytes() throws IOException {
|
||||
long oldPos = position();
|
||||
seek(0, SeekMode.SET);
|
||||
byte[] ret = readBytes((int) (long) available());
|
||||
seek(oldPos, SeekMode.SET);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(byte[] data) throws IOException {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
write(data[i] & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract int read() throws IOException;
|
||||
|
||||
@Override
|
||||
public abstract void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
@Override
|
||||
public void write(int val) throws IOException {
|
||||
//nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
//nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUI8(long addr) throws IOException {
|
||||
long curPos = position();
|
||||
seek(addr, SeekMode.SET);
|
||||
int val = readUI8();
|
||||
seek(curPos, SeekMode.SET);
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeWChar(String name) throws IOException {
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
writeUI16(name.charAt(i));
|
||||
}
|
||||
writeUI16(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readWChar() throws IOException {
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
do {
|
||||
char c = (char) readUI16();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
strBuilder.append(c);
|
||||
} while (true);
|
||||
return strBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pad8bytes() throws IOException {
|
||||
int pad8 = (int) (position() % 8);
|
||||
switch (pad8) {
|
||||
case 1:
|
||||
write(0);
|
||||
case 2:
|
||||
write(0);
|
||||
case 3:
|
||||
write(0);
|
||||
case 4:
|
||||
write(0);
|
||||
case 5:
|
||||
write(0);
|
||||
case 6:
|
||||
write(0);
|
||||
case 7:
|
||||
write(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOlderOffsetToThisPos(long savedPos) throws IOException {
|
||||
long curPos = position();
|
||||
long actual = curPos - savedPos;
|
||||
|
||||
seek(savedPos, SeekMode.SET);
|
||||
writeUI64(actual);
|
||||
seek(curPos, SeekMode.SET);
|
||||
}
|
||||
|
||||
public void setOlderOffsetToThisPosCheck(long savedPos, long expected) throws IOException {
|
||||
if (expected == 1) {
|
||||
return;
|
||||
}
|
||||
long curPos = position();
|
||||
long actual = curPos - savedPos;
|
||||
if (actual != expected) {
|
||||
throw new RuntimeException("Expected " + expected + " but found actual " + actual + ". Diff:" + ((actual - expected) > 0 ? "+" : "") + (actual - expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public abstract class AbstractDataStream implements DataStreamInterface {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
@Override
|
||||
public abstract Long available();
|
||||
|
||||
@Override
|
||||
public abstract long position();
|
||||
|
||||
@Override
|
||||
public long readUI64() throws IOException {
|
||||
long lsb = readUI32();
|
||||
long msb = readUI32();
|
||||
long result = msb << 32 | lsb;
|
||||
return result & 0xffffffffffffffffL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readSI64() throws IOException {
|
||||
long lsb = readUI32();
|
||||
long msb = readUI32();
|
||||
return msb << 32 | lsb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeSI64(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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readUI32() throws IOException {
|
||||
try {
|
||||
return (readUI8() | (readUI8() << 8) | (readUI8() << 16) | (readUI8() << 24));
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUI16() throws IOException {
|
||||
try {
|
||||
return (readUI8() | (readUI8() << 8)) & 0xffff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeUI16(int val) throws IOException {
|
||||
write(val & 0xff);
|
||||
write((val >> 8) & 0xff);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUI8() throws IOException {
|
||||
try {
|
||||
return read() & 0xff;
|
||||
} catch (EOFException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeUI8(int val) throws IOException {
|
||||
write(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat((int) readUI32());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeFloat(float val) throws IOException {
|
||||
return writeUI32(Float.floatToIntBits(val));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readBytes(int numBytes) throws IOException {
|
||||
byte[] ret = new byte[numBytes];
|
||||
for (int i = 0; i < numBytes; i++) {
|
||||
ret[i] = (byte) read();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public byte[] getAllBytes() throws IOException {
|
||||
long oldPos = position();
|
||||
seek(0, SeekMode.SET);
|
||||
byte[] ret = readBytes((int) (long) available());
|
||||
seek(oldPos, SeekMode.SET);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(byte[] data) throws IOException {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
write(data[i] & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract int read() throws IOException;
|
||||
|
||||
@Override
|
||||
public abstract void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
@Override
|
||||
public void write(int val) throws IOException {
|
||||
//nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
//nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readUI8(long addr) throws IOException {
|
||||
long curPos = position();
|
||||
seek(addr, SeekMode.SET);
|
||||
int val = readUI8();
|
||||
seek(curPos, SeekMode.SET);
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeWChar(String name) throws IOException {
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
writeUI16(name.charAt(i));
|
||||
}
|
||||
writeUI16(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readWChar() throws IOException {
|
||||
StringBuilder strBuilder = new StringBuilder();
|
||||
do {
|
||||
char c = (char) readUI16();
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
strBuilder.append(c);
|
||||
} while (true);
|
||||
return strBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pad8bytes() throws IOException {
|
||||
int pad8 = (int) (position() % 8);
|
||||
switch (pad8) {
|
||||
case 1:
|
||||
write(0);
|
||||
case 2:
|
||||
write(0);
|
||||
case 3:
|
||||
write(0);
|
||||
case 4:
|
||||
write(0);
|
||||
case 5:
|
||||
write(0);
|
||||
case 6:
|
||||
write(0);
|
||||
case 7:
|
||||
write(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOlderOffsetToThisPos(long savedPos) throws IOException {
|
||||
long curPos = position();
|
||||
long actual = curPos - savedPos;
|
||||
|
||||
seek(savedPos, SeekMode.SET);
|
||||
writeUI64(actual);
|
||||
seek(curPos, SeekMode.SET);
|
||||
}
|
||||
|
||||
public void setOlderOffsetToThisPosCheck(long savedPos, long expected) throws IOException {
|
||||
if (expected == 1) {
|
||||
return;
|
||||
}
|
||||
long curPos = position();
|
||||
long actual = curPos - savedPos;
|
||||
if (actual != expected) {
|
||||
throw new RuntimeException("Expected " + expected + " but found actual " + actual + ". Diff:" + ((actual - expected) > 0 ? "+" : "") + (actual - expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface DataStreamInterface extends ReadDataStreamInterface, WriteDataStreamInterface {
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface DataStreamInterface extends ReadDataStreamInterface, WriteDataStreamInterface {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,401 +1,401 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFontBinInfo;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFontTypeInfo;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyIndexBuilder {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyIndexBuilder.class.getName());
|
||||
private static final int CODE_FC_SKIP1 = 0xFC;
|
||||
private static final int CODE_FD_OFS8_SKIP_TWICE8 = 0xFD;
|
||||
private static final int CODE_FE_OFS8_POSITIVE = 0xFE;
|
||||
private static final int CODE_FF_OFS32 = 0xFF;
|
||||
|
||||
private List<Integer> constTable = new ArrayList<>();
|
||||
private Map<Integer, List<Integer>> constTableOffsets = new HashMap<>();
|
||||
private Map<Integer, List<Integer>> constTableTypes = new HashMap<>();
|
||||
private WriteDataStreamInterface indexStream;
|
||||
|
||||
private static final int CONST_VAL_SHAPE_NODE_SIZE = IggyShapeNode.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_KERNING_RECORD_SIZE = IggyCharKerning.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_CHAR_OFFSET_SIZE = IggyCharOffset.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_BIN_INFO_SIZE = IggyFontBinInfo.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_TYPE_INFO_SIZE = IggyFontTypeInfo.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_SHAPE_SIZE = IggyShape.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_GENERAL_FONT_INFO_SIZE = 112;
|
||||
private static final int CONST_VAL_GENERAL_FONT_INFO2_SIZE = 240;
|
||||
private static final int CONST_VAL_TEXT_DATA_SIZE = 104;
|
||||
private static final int CONST_VAL_SEQUENCE_SIZE = 16;
|
||||
|
||||
public static final int CONST_SHAPE_NODE_SIZE = 0;
|
||||
public static final int CONST_KERNING_RECORD_SIZE = 1;
|
||||
public static final int CONST_CHAR_OFFSET_SIZE = 2;
|
||||
public static final int CONST_BIN_INFO_SIZE = 3;
|
||||
public static final int CONST_TYPE_INFO_SIZE = 4;
|
||||
public static final int CONST_SHAPE_SIZE = 5;
|
||||
public static final int CONST_GENERAL_FONT_INFO_SIZE = 6;
|
||||
public static final int CONST_GENERAL_FONT_INFO2_SIZE = 7;
|
||||
public static final int CONST_TEXT_DATA_SIZE = 8;
|
||||
public static final int CONST_SEQUENCE_SIZE = 9;
|
||||
|
||||
private long position = 0;
|
||||
|
||||
public IggyIndexBuilder() throws IOException {
|
||||
indexStream = new TemporaryDataStream();
|
||||
|
||||
addConst(CONST_VAL_SHAPE_NODE_SIZE, new int[]{0, 4, 8, 0xC, 0x12, 0x14, 0x16}, new int[]{5, 5, 5, 5, 4, 4, 4});
|
||||
addConst(CONST_VAL_KERNING_RECORD_SIZE, new int[]{0, 2, 4}, new int[]{4, 4, 4});
|
||||
addConst(CONST_VAL_CHAR_OFFSET_SIZE, new int[]{8, 0x10, 0x18}, new int[]{4, 8, 2});
|
||||
addConst(CONST_VAL_BIN_INFO_SIZE, new int[]{0, 9, 0xC, 0x10, 0x14, 0x18, 0x1C, 0x20, 0x24, 0x28, 0x30, 0x38, 0x3A}, new int[]{2, 3, 5, 5, 5, 5, 5, 5, 5, 4, 2, 4, 4});
|
||||
addConst(CONST_VAL_TYPE_INFO_SIZE, new int[]{8, 0x10}, new int[]{2, 5});
|
||||
addConst(CONST_VAL_SHAPE_SIZE, new int[]{0, 4, 8, 0xC, 0x10, 0x18, 0x20, 0x28, 0x30}, new int[]{5, 5, 5, 5, 2, 5, 2, 2, 2});
|
||||
addConst(CONST_VAL_GENERAL_FONT_INFO_SIZE, new int[]{0x1, 0x02, 0x08, 0x10, 0x20, 0x22, 0x24, 0x26, 0x2B, 0x30, 0x38, 0x40, 0x48, 0x4C, 0x50, 0x54, 0x58, 0x60}, new int[]{0xC, 4, 5, 2, 4, 4, 4, 4, 3, 2, 2, 2, 5, 5, 5, 5, 5, 2});
|
||||
addConst(CONST_VAL_GENERAL_FONT_INFO2_SIZE, new int[]{0x10}, new int[]{2});
|
||||
addConst(CONST_VAL_TEXT_DATA_SIZE, new int[]{0x01, 0x02, 0x08, 0x10, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x32, 0x38, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x60}, new int[]{0x0C, 4, 5, 2, 5, 5, 5, 5, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2});
|
||||
addConst(CONST_VAL_SEQUENCE_SIZE, new int[]{0, 8}, new int[]{2, 5});
|
||||
}
|
||||
|
||||
private void addConst(int totalLength, int[] localOffsets, int[] types) {
|
||||
if (localOffsets.length != types.length) {
|
||||
throw new RuntimeException("Size of localOffsets does not match size of types on adding consts with total length " + totalLength);
|
||||
}
|
||||
constTable.add(totalLength);
|
||||
int newIndex = constTable.size() - 1;
|
||||
List<Integer> localOffsetsList = new ArrayList<>();
|
||||
for (int t : localOffsets) {
|
||||
localOffsetsList.add(t);
|
||||
}
|
||||
List<Integer> typesList = new ArrayList<>();
|
||||
for (int t : types) {
|
||||
typesList.add(t);
|
||||
}
|
||||
constTableOffsets.put(newIndex, localOffsetsList);
|
||||
constTableTypes.put(newIndex, typesList);
|
||||
}
|
||||
|
||||
private byte[] getIndexTableBytes() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
baos.write(constTable.size());
|
||||
for (int i = 0; i < constTable.size(); i++) {
|
||||
baos.write(constTable.get(i));
|
||||
baos.write(constTableOffsets.get(i).size());
|
||||
for (int j = 0; j < constTableOffsets.get(i).size(); j++) {
|
||||
baos.write(constTableOffsets.get(i).get(j));
|
||||
baos.write(constTableTypes.get(i).get(j));
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public byte[] getIndexBytes() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
baos.write(getIndexTableBytes());
|
||||
baos.write(indexStream.getAllBytes());
|
||||
} catch (IOException ex) {
|
||||
//should not happen
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public long writeConstLength(int constIndex) {
|
||||
return writeIndex(constIndex, false, 0);
|
||||
}
|
||||
|
||||
public long writeConstLengthArray(int constIndex, long cnt) {
|
||||
long ret = 0;
|
||||
long rem = cnt;
|
||||
while (true) {
|
||||
if (rem == 0) {
|
||||
break;
|
||||
}
|
||||
if (rem == 1) {
|
||||
ret += writeIndex(constIndex, false, 0);
|
||||
break;
|
||||
}
|
||||
if (rem <= 64) {
|
||||
ret += writeIndex(0x80 + (int) rem - 1, false, constIndex);
|
||||
break;
|
||||
} else {
|
||||
rem -= 64;
|
||||
ret += writeIndex(0x80 + 64 - 1, false, constIndex);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public long pad8bytes() {
|
||||
int pad8 = (int) (position % 8);
|
||||
switch (pad8) {
|
||||
case 2:
|
||||
writePaddingBytes(2); //+6
|
||||
break;
|
||||
case 4:
|
||||
writePaddingBytes(1); //+4
|
||||
break;
|
||||
case 6:
|
||||
writePaddingBytes(0); // +2
|
||||
break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long writeTwoPaddingBytes() {
|
||||
return writePaddingBytes(0);
|
||||
}
|
||||
|
||||
public long writePadding16bit() {
|
||||
return writePaddingBytes(0);
|
||||
}
|
||||
|
||||
public long writePadding32bit() {
|
||||
return writePaddingBytes(1);
|
||||
}
|
||||
|
||||
public long writePadding64bit() {
|
||||
return writePaddingBytes(2);
|
||||
}
|
||||
|
||||
public long writePaddingBytes(int twoPlusHowManyTwoBytes) {
|
||||
return writeIndex(0xC0 + twoPlusHowManyTwoBytes, false, 0);
|
||||
}
|
||||
|
||||
public long writePointerArray(boolean is64, long cnt) {
|
||||
return writeIndex(0xD0 + 0x2, is64, cnt - 1);
|
||||
}
|
||||
|
||||
public long write64bitPointerArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x2, true, cnt - 1);
|
||||
}
|
||||
|
||||
public long write32bitPointerArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x2, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long write16bitArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x4, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long write32bitArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x5, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long write64bitArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x6, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long skipOneInIndex() {
|
||||
return writeIndex(CODE_FC_SKIP1, false, 0);
|
||||
}
|
||||
|
||||
public long writeLengthCustom(int totalLen, int localOffsets[], int platformTypes[]) {
|
||||
return writeIndex(CODE_FD_OFS8_SKIP_TWICE8, false, totalLen, localOffsets, platformTypes);
|
||||
}
|
||||
|
||||
public long writeLengthBytePositive(int valUI8) {
|
||||
return writeIndex(CODE_FE_OFS8_POSITIVE, false, valUI8);
|
||||
}
|
||||
|
||||
public long writeLengthUI32(long offset) {
|
||||
return writeIndex(CODE_FF_OFS32, false, offset);
|
||||
}
|
||||
|
||||
public static int platformNumSize(boolean is64, int i) {
|
||||
if (i <= 2) {
|
||||
return is64 ? 8 : 4;
|
||||
} else if (i <= 4) {
|
||||
return 2;
|
||||
} else if (i == 5) {
|
||||
return 4;
|
||||
} else if (i == 6) {
|
||||
return 8;
|
||||
}
|
||||
throw new RuntimeException("Uknown platform num");
|
||||
}
|
||||
|
||||
private long writeIndex(int code, boolean is64, long val) {
|
||||
return writeIndex(code, is64, val, null, null);
|
||||
}
|
||||
|
||||
private long writeIndex(int code, boolean is64, long val, int localOffsets[], int platformTypes[]) {
|
||||
try {
|
||||
//LOGGER.finest(String.format("index offset: %d, %04X", STATIC_HDR.length + indexStream.position(), STATIC_HDR.length + indexStream.position()));
|
||||
LOGGER.finer(String.format("Code = 0x%02X", code));
|
||||
indexStream.writeUI8(code);
|
||||
if (code < 0x80) // 0-0x7F
|
||||
{
|
||||
LOGGER.finest("0-0x7F: code is directly an index to the index_table");
|
||||
// code is directly an index to the index_table
|
||||
if (code >= constTable.size()) {
|
||||
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x", code, constTable.size()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[%d] = %d", code, constTable.get(code)));
|
||||
long ret = constTable.get(code);
|
||||
position += ret;
|
||||
return ret;
|
||||
} else if (code < 0xC0) // 0x80-BF
|
||||
{
|
||||
LOGGER.finest("0x80-BF: table[0..255]*(code-0x7F)");
|
||||
int index;
|
||||
|
||||
indexStream.writeUI8((int) val);
|
||||
index = (int) val;
|
||||
|
||||
if (index >= constTable.size()) {
|
||||
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, constTable.size()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int n = code - 0x7F;
|
||||
LOGGER.finest(String.format("index = %d, n = code - 0x7F = %d", index, n));
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[index] * n = indexTable[%d] * %d = %d", index, n, constTable.get(index) * n));
|
||||
long ret = constTable.get(index) * n;
|
||||
position += ret;
|
||||
return ret;
|
||||
} else if (code < 0xD0) // 0xC0-0xCF
|
||||
{
|
||||
LOGGER.finest("0xC0-CF: code*2-0x17E");
|
||||
long ret = ((code * 2) - 0x17E);
|
||||
position += ret;
|
||||
return ret;
|
||||
} else if (code < 0xE0) // 0xD0-0xDF
|
||||
{
|
||||
LOGGER.finest("0xD0-0xDF: platform based");
|
||||
|
||||
// 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;
|
||||
|
||||
indexStream.writeUI8((int) val);
|
||||
if ((n8 = (int) val) < 0) {
|
||||
LOGGER.severe(String.format("< 0xE0: Cannot read n."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
|
||||
LOGGER.finest(String.format("i=%X", i));
|
||||
LOGGER.finest(String.format("n=%d", n));
|
||||
|
||||
if (is64) {
|
||||
if (i <= 2) {
|
||||
LOGGER.finest(String.format("offset += %d", 8 * n));
|
||||
position += 8 * n;
|
||||
return 8 * n; // Ptr type
|
||||
} else if (i <= 4) {
|
||||
LOGGER.finest(String.format("offset += %d", 2 * n));
|
||||
position += 2 * n;
|
||||
return 2 * n;
|
||||
} else if (i == 5) {
|
||||
LOGGER.finest(String.format("offset += %d", 4 * n));
|
||||
position += 4 * n;
|
||||
return 4 * n;
|
||||
} else if (i == 6) {
|
||||
LOGGER.finest(String.format("offset += %d", 8 * n));
|
||||
position += 8 * n;
|
||||
return 8 * n; // 64 bits type
|
||||
} else {
|
||||
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)", i, code));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch (i) {
|
||||
case 2:
|
||||
LOGGER.finest(String.format("offset += %d", 4 * n));
|
||||
position += 4 * n;
|
||||
return 4 * n; // Ptr type;
|
||||
case 4:
|
||||
LOGGER.finest(String.format("offset += %d", 2 * n));
|
||||
position += 2 * n;
|
||||
return 2 * n;
|
||||
case 5:
|
||||
LOGGER.finest(String.format("offset += %d", 4 * n));
|
||||
position += 4 * n;
|
||||
return 4 * n; // 32 bits type
|
||||
case 6:
|
||||
LOGGER.finest(String.format("offset += %d", 8 * n));
|
||||
position += 8 * n;
|
||||
return 8 * n;
|
||||
default:
|
||||
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)", i, code));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (code == CODE_FC_SKIP1) {
|
||||
LOGGER.finest(String.format("0xFC: skip 1 "));
|
||||
//indexStream.seek(1, SeekMode.CUR);
|
||||
indexStream.write(0); //??
|
||||
return 1; //seek 1
|
||||
} else if (code == CODE_FD_OFS8_SKIP_TWICE8) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255, skip 2 * 0..255 "));
|
||||
int n, m;
|
||||
|
||||
n = (int) val;
|
||||
indexStream.writeUI8((int) val);
|
||||
m = localOffsets.length;
|
||||
indexStream.writeUI8(localOffsets.length);
|
||||
|
||||
long offset = n;
|
||||
position += n;
|
||||
LOGGER.finest(String.format("offset += %d", n));
|
||||
for (int i = 0; i < localOffsets.length; i++) {
|
||||
indexStream.writeUI8(localOffsets[i]);
|
||||
indexStream.writeUI8(platformTypes[i]);
|
||||
}
|
||||
return offset;
|
||||
} else if (code == CODE_FE_OFS8_POSITIVE) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255 + 1 "));
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
indexStream.writeUI8((int) val);
|
||||
if ((n8 = (int) val) < 0) {
|
||||
LOGGER.severe(String.format("0xFE: Cannot read n."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
position += n;
|
||||
LOGGER.finest(String.format("offset += %d", n));
|
||||
return n;
|
||||
} else if (code == CODE_FF_OFS32) {
|
||||
LOGGER.finest(String.format("0xFF: 32bit "));
|
||||
long n;
|
||||
|
||||
indexStream.writeUI32(val);
|
||||
if ((n = val) < 0) {
|
||||
LOGGER.severe(String.format("0xFF: Cannot read n."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOGGER.finest(String.format("offset += %d", n));
|
||||
position += n;
|
||||
return n;
|
||||
} else {
|
||||
LOGGER.warning(String.format("Unrecognized code: %x", code));
|
||||
return 0;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharKerning;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyCharOffset;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFontBinInfo;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyFontTypeInfo;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShape;
|
||||
import com.jpexs.decompiler.flash.iggy.IggyShapeNode;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyIndexBuilder {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyIndexBuilder.class.getName());
|
||||
private static final int CODE_FC_SKIP1 = 0xFC;
|
||||
private static final int CODE_FD_OFS8_SKIP_TWICE8 = 0xFD;
|
||||
private static final int CODE_FE_OFS8_POSITIVE = 0xFE;
|
||||
private static final int CODE_FF_OFS32 = 0xFF;
|
||||
|
||||
private List<Integer> constTable = new ArrayList<>();
|
||||
private Map<Integer, List<Integer>> constTableOffsets = new HashMap<>();
|
||||
private Map<Integer, List<Integer>> constTableTypes = new HashMap<>();
|
||||
private WriteDataStreamInterface indexStream;
|
||||
|
||||
private static final int CONST_VAL_SHAPE_NODE_SIZE = IggyShapeNode.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_KERNING_RECORD_SIZE = IggyCharKerning.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_CHAR_OFFSET_SIZE = IggyCharOffset.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_BIN_INFO_SIZE = IggyFontBinInfo.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_TYPE_INFO_SIZE = IggyFontTypeInfo.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_SHAPE_SIZE = IggyShape.STRUCT_SIZE;
|
||||
private static final int CONST_VAL_GENERAL_FONT_INFO_SIZE = 112;
|
||||
private static final int CONST_VAL_GENERAL_FONT_INFO2_SIZE = 240;
|
||||
private static final int CONST_VAL_TEXT_DATA_SIZE = 104;
|
||||
private static final int CONST_VAL_SEQUENCE_SIZE = 16;
|
||||
|
||||
public static final int CONST_SHAPE_NODE_SIZE = 0;
|
||||
public static final int CONST_KERNING_RECORD_SIZE = 1;
|
||||
public static final int CONST_CHAR_OFFSET_SIZE = 2;
|
||||
public static final int CONST_BIN_INFO_SIZE = 3;
|
||||
public static final int CONST_TYPE_INFO_SIZE = 4;
|
||||
public static final int CONST_SHAPE_SIZE = 5;
|
||||
public static final int CONST_GENERAL_FONT_INFO_SIZE = 6;
|
||||
public static final int CONST_GENERAL_FONT_INFO2_SIZE = 7;
|
||||
public static final int CONST_TEXT_DATA_SIZE = 8;
|
||||
public static final int CONST_SEQUENCE_SIZE = 9;
|
||||
|
||||
private long position = 0;
|
||||
|
||||
public IggyIndexBuilder() throws IOException {
|
||||
indexStream = new TemporaryDataStream();
|
||||
|
||||
addConst(CONST_VAL_SHAPE_NODE_SIZE, new int[]{0, 4, 8, 0xC, 0x12, 0x14, 0x16}, new int[]{5, 5, 5, 5, 4, 4, 4});
|
||||
addConst(CONST_VAL_KERNING_RECORD_SIZE, new int[]{0, 2, 4}, new int[]{4, 4, 4});
|
||||
addConst(CONST_VAL_CHAR_OFFSET_SIZE, new int[]{8, 0x10, 0x18}, new int[]{4, 8, 2});
|
||||
addConst(CONST_VAL_BIN_INFO_SIZE, new int[]{0, 9, 0xC, 0x10, 0x14, 0x18, 0x1C, 0x20, 0x24, 0x28, 0x30, 0x38, 0x3A}, new int[]{2, 3, 5, 5, 5, 5, 5, 5, 5, 4, 2, 4, 4});
|
||||
addConst(CONST_VAL_TYPE_INFO_SIZE, new int[]{8, 0x10}, new int[]{2, 5});
|
||||
addConst(CONST_VAL_SHAPE_SIZE, new int[]{0, 4, 8, 0xC, 0x10, 0x18, 0x20, 0x28, 0x30}, new int[]{5, 5, 5, 5, 2, 5, 2, 2, 2});
|
||||
addConst(CONST_VAL_GENERAL_FONT_INFO_SIZE, new int[]{0x1, 0x02, 0x08, 0x10, 0x20, 0x22, 0x24, 0x26, 0x2B, 0x30, 0x38, 0x40, 0x48, 0x4C, 0x50, 0x54, 0x58, 0x60}, new int[]{0xC, 4, 5, 2, 4, 4, 4, 4, 3, 2, 2, 2, 5, 5, 5, 5, 5, 2});
|
||||
addConst(CONST_VAL_GENERAL_FONT_INFO2_SIZE, new int[]{0x10}, new int[]{2});
|
||||
addConst(CONST_VAL_TEXT_DATA_SIZE, new int[]{0x01, 0x02, 0x08, 0x10, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x32, 0x38, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x60}, new int[]{0x0C, 4, 5, 2, 5, 5, 5, 5, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2});
|
||||
addConst(CONST_VAL_SEQUENCE_SIZE, new int[]{0, 8}, new int[]{2, 5});
|
||||
}
|
||||
|
||||
private void addConst(int totalLength, int[] localOffsets, int[] types) {
|
||||
if (localOffsets.length != types.length) {
|
||||
throw new RuntimeException("Size of localOffsets does not match size of types on adding consts with total length " + totalLength);
|
||||
}
|
||||
constTable.add(totalLength);
|
||||
int newIndex = constTable.size() - 1;
|
||||
List<Integer> localOffsetsList = new ArrayList<>();
|
||||
for (int t : localOffsets) {
|
||||
localOffsetsList.add(t);
|
||||
}
|
||||
List<Integer> typesList = new ArrayList<>();
|
||||
for (int t : types) {
|
||||
typesList.add(t);
|
||||
}
|
||||
constTableOffsets.put(newIndex, localOffsetsList);
|
||||
constTableTypes.put(newIndex, typesList);
|
||||
}
|
||||
|
||||
private byte[] getIndexTableBytes() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
baos.write(constTable.size());
|
||||
for (int i = 0; i < constTable.size(); i++) {
|
||||
baos.write(constTable.get(i));
|
||||
baos.write(constTableOffsets.get(i).size());
|
||||
for (int j = 0; j < constTableOffsets.get(i).size(); j++) {
|
||||
baos.write(constTableOffsets.get(i).get(j));
|
||||
baos.write(constTableTypes.get(i).get(j));
|
||||
}
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public byte[] getIndexBytes() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
baos.write(getIndexTableBytes());
|
||||
baos.write(indexStream.getAllBytes());
|
||||
} catch (IOException ex) {
|
||||
//should not happen
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public long writeConstLength(int constIndex) {
|
||||
return writeIndex(constIndex, false, 0);
|
||||
}
|
||||
|
||||
public long writeConstLengthArray(int constIndex, long cnt) {
|
||||
long ret = 0;
|
||||
long rem = cnt;
|
||||
while (true) {
|
||||
if (rem == 0) {
|
||||
break;
|
||||
}
|
||||
if (rem == 1) {
|
||||
ret += writeIndex(constIndex, false, 0);
|
||||
break;
|
||||
}
|
||||
if (rem <= 64) {
|
||||
ret += writeIndex(0x80 + (int) rem - 1, false, constIndex);
|
||||
break;
|
||||
} else {
|
||||
rem -= 64;
|
||||
ret += writeIndex(0x80 + 64 - 1, false, constIndex);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public long pad8bytes() {
|
||||
int pad8 = (int) (position % 8);
|
||||
switch (pad8) {
|
||||
case 2:
|
||||
writePaddingBytes(2); //+6
|
||||
break;
|
||||
case 4:
|
||||
writePaddingBytes(1); //+4
|
||||
break;
|
||||
case 6:
|
||||
writePaddingBytes(0); // +2
|
||||
break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long writeTwoPaddingBytes() {
|
||||
return writePaddingBytes(0);
|
||||
}
|
||||
|
||||
public long writePadding16bit() {
|
||||
return writePaddingBytes(0);
|
||||
}
|
||||
|
||||
public long writePadding32bit() {
|
||||
return writePaddingBytes(1);
|
||||
}
|
||||
|
||||
public long writePadding64bit() {
|
||||
return writePaddingBytes(2);
|
||||
}
|
||||
|
||||
public long writePaddingBytes(int twoPlusHowManyTwoBytes) {
|
||||
return writeIndex(0xC0 + twoPlusHowManyTwoBytes, false, 0);
|
||||
}
|
||||
|
||||
public long writePointerArray(boolean is64, long cnt) {
|
||||
return writeIndex(0xD0 + 0x2, is64, cnt - 1);
|
||||
}
|
||||
|
||||
public long write64bitPointerArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x2, true, cnt - 1);
|
||||
}
|
||||
|
||||
public long write32bitPointerArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x2, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long write16bitArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x4, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long write32bitArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x5, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long write64bitArray(long cnt) {
|
||||
return writeIndex(0xD0 + 0x6, false, cnt - 1);
|
||||
}
|
||||
|
||||
public long skipOneInIndex() {
|
||||
return writeIndex(CODE_FC_SKIP1, false, 0);
|
||||
}
|
||||
|
||||
public long writeLengthCustom(int totalLen, int localOffsets[], int platformTypes[]) {
|
||||
return writeIndex(CODE_FD_OFS8_SKIP_TWICE8, false, totalLen, localOffsets, platformTypes);
|
||||
}
|
||||
|
||||
public long writeLengthBytePositive(int valUI8) {
|
||||
return writeIndex(CODE_FE_OFS8_POSITIVE, false, valUI8);
|
||||
}
|
||||
|
||||
public long writeLengthUI32(long offset) {
|
||||
return writeIndex(CODE_FF_OFS32, false, offset);
|
||||
}
|
||||
|
||||
public static int platformNumSize(boolean is64, int i) {
|
||||
if (i <= 2) {
|
||||
return is64 ? 8 : 4;
|
||||
} else if (i <= 4) {
|
||||
return 2;
|
||||
} else if (i == 5) {
|
||||
return 4;
|
||||
} else if (i == 6) {
|
||||
return 8;
|
||||
}
|
||||
throw new RuntimeException("Uknown platform num");
|
||||
}
|
||||
|
||||
private long writeIndex(int code, boolean is64, long val) {
|
||||
return writeIndex(code, is64, val, null, null);
|
||||
}
|
||||
|
||||
private long writeIndex(int code, boolean is64, long val, int localOffsets[], int platformTypes[]) {
|
||||
try {
|
||||
//LOGGER.finest(String.format("index offset: %d, %04X", STATIC_HDR.length + indexStream.position(), STATIC_HDR.length + indexStream.position()));
|
||||
LOGGER.finer(String.format("Code = 0x%02X", code));
|
||||
indexStream.writeUI8(code);
|
||||
if (code < 0x80) // 0-0x7F
|
||||
{
|
||||
LOGGER.finest("0-0x7F: code is directly an index to the index_table");
|
||||
// code is directly an index to the index_table
|
||||
if (code >= constTable.size()) {
|
||||
LOGGER.severe(String.format("< 0x80: index is greater than index_table_size. %x > %x", code, constTable.size()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[%d] = %d", code, constTable.get(code)));
|
||||
long ret = constTable.get(code);
|
||||
position += ret;
|
||||
return ret;
|
||||
} else if (code < 0xC0) // 0x80-BF
|
||||
{
|
||||
LOGGER.finest("0x80-BF: table[0..255]*(code-0x7F)");
|
||||
int index;
|
||||
|
||||
indexStream.writeUI8((int) val);
|
||||
index = (int) val;
|
||||
|
||||
if (index >= constTable.size()) {
|
||||
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, constTable.size()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int n = code - 0x7F;
|
||||
LOGGER.finest(String.format("index = %d, n = code - 0x7F = %d", index, n));
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[index] * n = indexTable[%d] * %d = %d", index, n, constTable.get(index) * n));
|
||||
long ret = constTable.get(index) * n;
|
||||
position += ret;
|
||||
return ret;
|
||||
} else if (code < 0xD0) // 0xC0-0xCF
|
||||
{
|
||||
LOGGER.finest("0xC0-CF: code*2-0x17E");
|
||||
long ret = ((code * 2) - 0x17E);
|
||||
position += ret;
|
||||
return ret;
|
||||
} else if (code < 0xE0) // 0xD0-0xDF
|
||||
{
|
||||
LOGGER.finest("0xD0-0xDF: platform based");
|
||||
|
||||
// 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;
|
||||
|
||||
indexStream.writeUI8((int) val);
|
||||
if ((n8 = (int) val) < 0) {
|
||||
LOGGER.severe(String.format("< 0xE0: Cannot read n."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
|
||||
LOGGER.finest(String.format("i=%X", i));
|
||||
LOGGER.finest(String.format("n=%d", n));
|
||||
|
||||
if (is64) {
|
||||
if (i <= 2) {
|
||||
LOGGER.finest(String.format("offset += %d", 8 * n));
|
||||
position += 8 * n;
|
||||
return 8 * n; // Ptr type
|
||||
} else if (i <= 4) {
|
||||
LOGGER.finest(String.format("offset += %d", 2 * n));
|
||||
position += 2 * n;
|
||||
return 2 * n;
|
||||
} else if (i == 5) {
|
||||
LOGGER.finest(String.format("offset += %d", 4 * n));
|
||||
position += 4 * n;
|
||||
return 4 * n;
|
||||
} else if (i == 6) {
|
||||
LOGGER.finest(String.format("offset += %d", 8 * n));
|
||||
position += 8 * n;
|
||||
return 8 * n; // 64 bits type
|
||||
} else {
|
||||
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)", i, code));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
switch (i) {
|
||||
case 2:
|
||||
LOGGER.finest(String.format("offset += %d", 4 * n));
|
||||
position += 4 * n;
|
||||
return 4 * n; // Ptr type;
|
||||
case 4:
|
||||
LOGGER.finest(String.format("offset += %d", 2 * n));
|
||||
position += 2 * n;
|
||||
return 2 * n;
|
||||
case 5:
|
||||
LOGGER.finest(String.format("offset += %d", 4 * n));
|
||||
position += 4 * n;
|
||||
return 4 * n; // 32 bits type
|
||||
case 6:
|
||||
LOGGER.finest(String.format("offset += %d", 8 * n));
|
||||
position += 8 * n;
|
||||
return 8 * n;
|
||||
default:
|
||||
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)", i, code));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (code == CODE_FC_SKIP1) {
|
||||
LOGGER.finest(String.format("0xFC: skip 1 "));
|
||||
//indexStream.seek(1, SeekMode.CUR);
|
||||
indexStream.write(0); //??
|
||||
return 1; //seek 1
|
||||
} else if (code == CODE_FD_OFS8_SKIP_TWICE8) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255, skip 2 * 0..255 "));
|
||||
int n, m;
|
||||
|
||||
n = (int) val;
|
||||
indexStream.writeUI8((int) val);
|
||||
m = localOffsets.length;
|
||||
indexStream.writeUI8(localOffsets.length);
|
||||
|
||||
long offset = n;
|
||||
position += n;
|
||||
LOGGER.finest(String.format("offset += %d", n));
|
||||
for (int i = 0; i < localOffsets.length; i++) {
|
||||
indexStream.writeUI8(localOffsets[i]);
|
||||
indexStream.writeUI8(platformTypes[i]);
|
||||
}
|
||||
return offset;
|
||||
} else if (code == CODE_FE_OFS8_POSITIVE) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255 + 1 "));
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
indexStream.writeUI8((int) val);
|
||||
if ((n8 = (int) val) < 0) {
|
||||
LOGGER.severe(String.format("0xFE: Cannot read n."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
position += n;
|
||||
LOGGER.finest(String.format("offset += %d", n));
|
||||
return n;
|
||||
} else if (code == CODE_FF_OFS32) {
|
||||
LOGGER.finest(String.format("0xFF: 32bit "));
|
||||
long n;
|
||||
|
||||
indexStream.writeUI32(val);
|
||||
if ((n = val) < 0) {
|
||||
LOGGER.severe(String.format("0xFF: Cannot read n."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOGGER.finest(String.format("offset += %d", n));
|
||||
position += n;
|
||||
return n;
|
||||
} else {
|
||||
LOGGER.warning(String.format("Unrecognized code: %x", code));
|
||||
return 0;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,246 +1,246 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyIndexParser {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyIndexParser.class.getName());
|
||||
|
||||
/*static PrintWriter pw;
|
||||
|
||||
static {
|
||||
try {
|
||||
pw = new PrintWriter("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_orig\\index2b.txt");
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(IggyIndexParser.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
LOGGER.setLevel(Level.ALL);
|
||||
LOGGER.addHandler(new Handler() {
|
||||
@Override
|
||||
public void publish(LogRecord record) {
|
||||
pw.println("" + record.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
pw.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SecurityException {
|
||||
pw.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* 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(boolean is64, ReadDataStreamInterface 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: %d", offset));
|
||||
indexTable[i] = offset;
|
||||
indexTableEntry.add(offset);
|
||||
int num = indexStream.readUI8();
|
||||
for (int j = 0; j < num; j++) {
|
||||
int locOffset = indexStream.readUI8();
|
||||
int type = indexStream.readUI8();
|
||||
LOGGER.finer(String.format("- local offset: %d, type: %d", locOffset, type));
|
||||
}
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
int code;
|
||||
|
||||
String tabs = "\t\t\t\t";
|
||||
|
||||
LOGGER.finer(String.format("-- OFFSET: 0" + tabs));
|
||||
|
||||
while ((code = indexStream.readUI8()) > -1) {
|
||||
LOGGER.finer(String.format("Code = 0x%02X", code));
|
||||
|
||||
if (code < 0x80) // 0-0x7F
|
||||
{
|
||||
LOGGER.finest("0-0x7F: code is directly an index to the index_table");
|
||||
// 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", code, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += indexTable[code];
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[%d] = %d", code, indexTable[code]));
|
||||
|
||||
} else if (code < 0xC0) // 0x80-BF
|
||||
{
|
||||
LOGGER.finest("0x80-BF: table[0..255]*(code-0x7F)");
|
||||
int index;
|
||||
|
||||
if ((index = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("< 0xC0: Cannot read index."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= indexTableSize) {
|
||||
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
int n = code - 0x7F;
|
||||
LOGGER.finest(String.format("index = %d, n = code - 0x7F = %d", index, n));
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[index] * n = indexTable[%d] * %d = %d", index, n, indexTable[index] * n));
|
||||
offset += indexTable[index] * n;
|
||||
} else if (code < 0xD0) // 0xC0-0xCF
|
||||
{
|
||||
LOGGER.finest("0xC0-CF: code*2-0x17E");
|
||||
offset += ((code * 2) - 0x17E);
|
||||
LOGGER.finest(String.format("LENGTH = (code * 2) - 0x17E = (0x%02X * 2) - 0x17E = %d", code, ((code * 2) - 0x17E)));
|
||||
} else if (code < 0xE0) // 0xD0-0xDF
|
||||
{
|
||||
LOGGER.finest("0xD0-0xDF: platform based");
|
||||
|
||||
// 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."));
|
||||
return;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
|
||||
LOGGER.finest(String.format("i=%X", i));
|
||||
LOGGER.finest(String.format("n=%d", n));
|
||||
|
||||
if (is64) {
|
||||
if (i <= 2) {
|
||||
offset += 8 * n; // Ptr type
|
||||
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
|
||||
} else if (i <= 4) {
|
||||
offset += 2 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 2 * n = 2 * %d = %d", n, 2 * n));
|
||||
} else if (i == 5) {
|
||||
offset += 4 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
|
||||
} else if (i == 6) {
|
||||
offset += 8 * n; // 64 bits type
|
||||
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
|
||||
} else {
|
||||
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)", i, code));
|
||||
}
|
||||
} else {
|
||||
switch (i) {
|
||||
case 2:
|
||||
offset += 4 * n; // Ptr type
|
||||
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
|
||||
break;
|
||||
case 4:
|
||||
offset += 2 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 2 * n = 2 * %d = %d", n, 2 * n));
|
||||
break;
|
||||
case 5:
|
||||
offset += 4 * n; // 32 bits type
|
||||
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
|
||||
break;
|
||||
case 6:
|
||||
offset += 8 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
|
||||
break;
|
||||
default:
|
||||
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)", i, code));
|
||||
}
|
||||
}
|
||||
} else if (code == 0xFC) {
|
||||
LOGGER.finest(String.format("0xFC: SKIP 1 "));
|
||||
indexStream.seek(1, SeekMode.CUR);
|
||||
} else if (code == 0xFD) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255, skip 2 * 0..255 "));
|
||||
int n, m;
|
||||
|
||||
if ((n = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read n."));
|
||||
return;
|
||||
}
|
||||
LOGGER.finest(String.format("n = %d", n));
|
||||
|
||||
if ((m = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read m."));
|
||||
return;
|
||||
}
|
||||
LOGGER.finest(String.format("m = %d", m));
|
||||
|
||||
offset += n;
|
||||
LOGGER.finest(String.format("LENGTH = n = %d", n));
|
||||
StringBuilder locOffStr = new StringBuilder();
|
||||
StringBuilder platStr = new StringBuilder();
|
||||
for (int i = 0; i < m; i++) {
|
||||
int localOffset = indexStream.readUI8();
|
||||
int platformType = indexStream.readUI8();
|
||||
if (i > 0) {
|
||||
locOffStr.append(", ");
|
||||
platStr.append(", ");
|
||||
}
|
||||
locOffStr.append(String.format("0x%02X", localOffset));
|
||||
platStr.append(platformType);
|
||||
LOGGER.finest(String.format("- localOffset 0x%02X, platformType %d", localOffset, platformType));
|
||||
}
|
||||
LOGGER.finer(String.format("stream.writeLengthCustom(%s,new int[]{%s},new int[]{%s}", n, locOffStr, platStr));
|
||||
//indexStream.seek(m * 2, SeekMode.CUR);
|
||||
//LOGGER.finest(String.format("SKIP m * 2 = skip %d * 2 = %d", m, m * 2));
|
||||
} else if (code == 0xFE) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255 + 1 "));
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
if ((n8 = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFE: Cannot read n."));
|
||||
return;
|
||||
}
|
||||
LOGGER.finest(String.format("n8 = %d", n8));
|
||||
|
||||
n = n8 + 1;
|
||||
offset += n;
|
||||
LOGGER.finest(String.format("LENGTH = n8 + 1 = %d + 1 = %d", n8, n));
|
||||
} else if (code == 0xFF) {
|
||||
LOGGER.finest(String.format("0xFF: 32bit "));
|
||||
long n;
|
||||
|
||||
if ((n = indexStream.readUI32()) < 0) {
|
||||
LOGGER.severe(String.format("0xFF: Cannot read n."));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
LOGGER.finest(String.format("LENGTH = n = %d", n));
|
||||
} else {
|
||||
LOGGER.warning(String.format("Unrecognized code: %x", code));
|
||||
}
|
||||
|
||||
LOGGER.finer(String.format("-- OFFSET: %d" + tabs, offset));
|
||||
|
||||
offsets.add(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.List;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class IggyIndexParser {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(IggyIndexParser.class.getName());
|
||||
|
||||
/*static PrintWriter pw;
|
||||
|
||||
static {
|
||||
try {
|
||||
pw = new PrintWriter("d:\\Dropbox\\jpexs-laptop\\iggi\\extraxtdir_orig\\index2b.txt");
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(IggyIndexParser.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
LOGGER.setLevel(Level.ALL);
|
||||
LOGGER.addHandler(new Handler() {
|
||||
@Override
|
||||
public void publish(LogRecord record) {
|
||||
pw.println("" + record.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
pw.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SecurityException {
|
||||
pw.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* 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(boolean is64, ReadDataStreamInterface 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: %d", offset));
|
||||
indexTable[i] = offset;
|
||||
indexTableEntry.add(offset);
|
||||
int num = indexStream.readUI8();
|
||||
for (int j = 0; j < num; j++) {
|
||||
int locOffset = indexStream.readUI8();
|
||||
int type = indexStream.readUI8();
|
||||
LOGGER.finer(String.format("- local offset: %d, type: %d", locOffset, type));
|
||||
}
|
||||
}
|
||||
|
||||
long offset = 0;
|
||||
int code;
|
||||
|
||||
String tabs = "\t\t\t\t";
|
||||
|
||||
LOGGER.finer(String.format("-- OFFSET: 0" + tabs));
|
||||
|
||||
while ((code = indexStream.readUI8()) > -1) {
|
||||
LOGGER.finer(String.format("Code = 0x%02X", code));
|
||||
|
||||
if (code < 0x80) // 0-0x7F
|
||||
{
|
||||
LOGGER.finest("0-0x7F: code is directly an index to the index_table");
|
||||
// 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", code, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += indexTable[code];
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[%d] = %d", code, indexTable[code]));
|
||||
|
||||
} else if (code < 0xC0) // 0x80-BF
|
||||
{
|
||||
LOGGER.finest("0x80-BF: table[0..255]*(code-0x7F)");
|
||||
int index;
|
||||
|
||||
if ((index = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("< 0xC0: Cannot read index."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= indexTableSize) {
|
||||
LOGGER.severe(String.format("< 0xC0: index is greater than index_table_size. %x > %x", index, indexTableSize));
|
||||
return;
|
||||
}
|
||||
|
||||
int n = code - 0x7F;
|
||||
LOGGER.finest(String.format("index = %d, n = code - 0x7F = %d", index, n));
|
||||
LOGGER.finest(String.format("LENGTH = indexTable[index] * n = indexTable[%d] * %d = %d", index, n, indexTable[index] * n));
|
||||
offset += indexTable[index] * n;
|
||||
} else if (code < 0xD0) // 0xC0-0xCF
|
||||
{
|
||||
LOGGER.finest("0xC0-CF: code*2-0x17E");
|
||||
offset += ((code * 2) - 0x17E);
|
||||
LOGGER.finest(String.format("LENGTH = (code * 2) - 0x17E = (0x%02X * 2) - 0x17E = %d", code, ((code * 2) - 0x17E)));
|
||||
} else if (code < 0xE0) // 0xD0-0xDF
|
||||
{
|
||||
LOGGER.finest("0xD0-0xDF: platform based");
|
||||
|
||||
// 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."));
|
||||
return;
|
||||
}
|
||||
|
||||
n = n8 + 1;
|
||||
|
||||
LOGGER.finest(String.format("i=%X", i));
|
||||
LOGGER.finest(String.format("n=%d", n));
|
||||
|
||||
if (is64) {
|
||||
if (i <= 2) {
|
||||
offset += 8 * n; // Ptr type
|
||||
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
|
||||
} else if (i <= 4) {
|
||||
offset += 2 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 2 * n = 2 * %d = %d", n, 2 * n));
|
||||
} else if (i == 5) {
|
||||
offset += 4 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
|
||||
} else if (i == 6) {
|
||||
offset += 8 * n; // 64 bits type
|
||||
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
|
||||
} else {
|
||||
LOGGER.severe(String.format("< 0xE0: Invalid value for i (%x %x)", i, code));
|
||||
}
|
||||
} else {
|
||||
switch (i) {
|
||||
case 2:
|
||||
offset += 4 * n; // Ptr type
|
||||
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
|
||||
break;
|
||||
case 4:
|
||||
offset += 2 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 2 * n = 2 * %d = %d", n, 2 * n));
|
||||
break;
|
||||
case 5:
|
||||
offset += 4 * n; // 32 bits type
|
||||
LOGGER.finest(String.format("LENGTH = 4 * n = 4 * %d = %d", n, 4 * n));
|
||||
break;
|
||||
case 6:
|
||||
offset += 8 * n;
|
||||
LOGGER.finest(String.format("LENGTH = 8 * n = 8 * %d = %d", n, 8 * n));
|
||||
break;
|
||||
default:
|
||||
LOGGER.severe(String.format("< 0xE0: invalid value for i (%x %x)", i, code));
|
||||
}
|
||||
}
|
||||
} else if (code == 0xFC) {
|
||||
LOGGER.finest(String.format("0xFC: SKIP 1 "));
|
||||
indexStream.seek(1, SeekMode.CUR);
|
||||
} else if (code == 0xFD) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255, skip 2 * 0..255 "));
|
||||
int n, m;
|
||||
|
||||
if ((n = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read n."));
|
||||
return;
|
||||
}
|
||||
LOGGER.finest(String.format("n = %d", n));
|
||||
|
||||
if ((m = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFD: Cannot read m."));
|
||||
return;
|
||||
}
|
||||
LOGGER.finest(String.format("m = %d", m));
|
||||
|
||||
offset += n;
|
||||
LOGGER.finest(String.format("LENGTH = n = %d", n));
|
||||
StringBuilder locOffStr = new StringBuilder();
|
||||
StringBuilder platStr = new StringBuilder();
|
||||
for (int i = 0; i < m; i++) {
|
||||
int localOffset = indexStream.readUI8();
|
||||
int platformType = indexStream.readUI8();
|
||||
if (i > 0) {
|
||||
locOffStr.append(", ");
|
||||
platStr.append(", ");
|
||||
}
|
||||
locOffStr.append(String.format("0x%02X", localOffset));
|
||||
platStr.append(platformType);
|
||||
LOGGER.finest(String.format("- localOffset 0x%02X, platformType %d", localOffset, platformType));
|
||||
}
|
||||
LOGGER.finer(String.format("stream.writeLengthCustom(%s,new int[]{%s},new int[]{%s}", n, locOffStr, platStr));
|
||||
//indexStream.seek(m * 2, SeekMode.CUR);
|
||||
//LOGGER.finest(String.format("SKIP m * 2 = skip %d * 2 = %d", m, m * 2));
|
||||
} else if (code == 0xFE) {
|
||||
LOGGER.finest(String.format("0xFD: 0..255 + 1 "));
|
||||
int n8;
|
||||
int n;
|
||||
|
||||
if ((n8 = indexStream.readUI8()) < 0) {
|
||||
LOGGER.severe(String.format("0xFE: Cannot read n."));
|
||||
return;
|
||||
}
|
||||
LOGGER.finest(String.format("n8 = %d", n8));
|
||||
|
||||
n = n8 + 1;
|
||||
offset += n;
|
||||
LOGGER.finest(String.format("LENGTH = n8 + 1 = %d + 1 = %d", n8, n));
|
||||
} else if (code == 0xFF) {
|
||||
LOGGER.finest(String.format("0xFF: 32bit "));
|
||||
long n;
|
||||
|
||||
if ((n = indexStream.readUI32()) < 0) {
|
||||
LOGGER.severe(String.format("0xFF: Cannot read n."));
|
||||
return;
|
||||
}
|
||||
|
||||
offset += n;
|
||||
LOGGER.finest(String.format("LENGTH = n = %d", n));
|
||||
} else {
|
||||
LOGGER.warning(String.format("Unrecognized code: %x", code));
|
||||
}
|
||||
|
||||
LOGGER.finer(String.format("-- OFFSET: %d" + tabs, offset));
|
||||
|
||||
offsets.add(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,128 +1,128 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RandomAccessFileDataStream extends AbstractDataStream {
|
||||
|
||||
private File file;
|
||||
private RandomAccessFile raf;
|
||||
private IggyIndexBuilder indexing;
|
||||
|
||||
protected File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndexing(IggyIndexBuilder indexing) {
|
||||
this.indexing = indexing;
|
||||
}
|
||||
|
||||
public RandomAccessFileDataStream(File file) throws FileNotFoundException {
|
||||
this.file = file;
|
||||
raf = new RandomAccessFile(file, "rw");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long totalSize() {
|
||||
try {
|
||||
return raf.length();
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long available() {
|
||||
try {
|
||||
return raf.length() - raf.getFilePointer();
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long position() {
|
||||
try {
|
||||
return raf.getFilePointer();
|
||||
} catch (IOException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
int val = raf.read();
|
||||
if (val == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readBytes(int numBytes) throws IOException {
|
||||
byte buf[] = new byte[numBytes];
|
||||
raf.readFully(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long pos, SeekMode mode) throws IOException {
|
||||
long newpos = pos;
|
||||
if (mode == SeekMode.CUR) {
|
||||
newpos = raf.getFilePointer() + pos;
|
||||
} else if (mode == SeekMode.END) {
|
||||
newpos = raf.length() - pos;
|
||||
}
|
||||
if (newpos > raf.length()) {
|
||||
raf.seek(raf.length());
|
||||
long curpos = raf.length();
|
||||
for (long i = curpos; i < newpos; i++) {
|
||||
raf.write(0);
|
||||
}
|
||||
} else if (newpos < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("Negative position accessed: " + pos);
|
||||
} else {
|
||||
raf.seek(newpos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
raf.close();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int val) throws IOException {
|
||||
raf.write(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IggyIndexBuilder getIndexing() {
|
||||
return indexing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeWChar(String name) throws IOException {
|
||||
return super.writeWChar(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pad8bytes() throws IOException {
|
||||
super.pad8bytes();
|
||||
}
|
||||
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class RandomAccessFileDataStream extends AbstractDataStream {
|
||||
|
||||
private File file;
|
||||
private RandomAccessFile raf;
|
||||
private IggyIndexBuilder indexing;
|
||||
|
||||
protected File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIndexing(IggyIndexBuilder indexing) {
|
||||
this.indexing = indexing;
|
||||
}
|
||||
|
||||
public RandomAccessFileDataStream(File file) throws FileNotFoundException {
|
||||
this.file = file;
|
||||
raf = new RandomAccessFile(file, "rw");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long totalSize() {
|
||||
try {
|
||||
return raf.length();
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long available() {
|
||||
try {
|
||||
return raf.length() - raf.getFilePointer();
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long position() {
|
||||
try {
|
||||
return raf.getFilePointer();
|
||||
} catch (IOException ex) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
int val = raf.read();
|
||||
if (val == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readBytes(int numBytes) throws IOException {
|
||||
byte buf[] = new byte[numBytes];
|
||||
raf.readFully(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(long pos, SeekMode mode) throws IOException {
|
||||
long newpos = pos;
|
||||
if (mode == SeekMode.CUR) {
|
||||
newpos = raf.getFilePointer() + pos;
|
||||
} else if (mode == SeekMode.END) {
|
||||
newpos = raf.length() - pos;
|
||||
}
|
||||
if (newpos > raf.length()) {
|
||||
raf.seek(raf.length());
|
||||
long curpos = raf.length();
|
||||
for (long i = curpos; i < newpos; i++) {
|
||||
raf.write(0);
|
||||
}
|
||||
} else if (newpos < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("Negative position accessed: " + pos);
|
||||
} else {
|
||||
raf.seek(newpos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
raf.close();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int val) throws IOException {
|
||||
raf.write(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IggyIndexBuilder getIndexing() {
|
||||
return indexing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeWChar(String name) throws IOException {
|
||||
return super.writeWChar(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pad8bytes() throws IOException {
|
||||
super.pad8bytes();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface ReadDataStreamInterface extends AutoCloseable {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
public Long available();
|
||||
|
||||
public Long totalSize();
|
||||
|
||||
public long position();
|
||||
|
||||
public long readUI64() throws IOException;
|
||||
|
||||
public long readSI64() throws IOException;
|
||||
|
||||
public long readUI32() throws IOException;
|
||||
|
||||
public int readUI16() throws IOException;
|
||||
|
||||
public int readUI8() throws IOException;
|
||||
|
||||
public int readUI8(long addr) throws IOException;
|
||||
|
||||
public int read() throws IOException;
|
||||
|
||||
public byte[] readBytes(int numBytes) throws IOException;
|
||||
|
||||
public float readFloat() throws IOException;
|
||||
|
||||
public void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
public byte[] getAllBytes() throws IOException;
|
||||
|
||||
public String readWChar() throws IOException;
|
||||
|
||||
public void pad8bytes() throws IOException;
|
||||
|
||||
@Override
|
||||
public void close();
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface ReadDataStreamInterface extends AutoCloseable {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
public Long available();
|
||||
|
||||
public Long totalSize();
|
||||
|
||||
public long position();
|
||||
|
||||
public long readUI64() throws IOException;
|
||||
|
||||
public long readSI64() throws IOException;
|
||||
|
||||
public long readUI32() throws IOException;
|
||||
|
||||
public int readUI16() throws IOException;
|
||||
|
||||
public int readUI8() throws IOException;
|
||||
|
||||
public int readUI8(long addr) throws IOException;
|
||||
|
||||
public int read() throws IOException;
|
||||
|
||||
public byte[] readBytes(int numBytes) throws IOException;
|
||||
|
||||
public float readFloat() throws IOException;
|
||||
|
||||
public void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
public byte[] getAllBytes() throws IOException;
|
||||
|
||||
public String readWChar() throws IOException;
|
||||
|
||||
public void pad8bytes() throws IOException;
|
||||
|
||||
@Override
|
||||
public void close();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*/
|
||||
public enum SeekMode {
|
||||
SET, CUR, END
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jindra
|
||||
*/
|
||||
public enum SeekMode {
|
||||
SET, CUR, END
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface StructureInterface {
|
||||
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException;
|
||||
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException;
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import com.jpexs.decompiler.flash.iggy.streams.AbstractDataStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface StructureInterface {
|
||||
|
||||
public void readFromDataStream(ReadDataStreamInterface stream) throws IOException;
|
||||
|
||||
public void writeToDataStream(WriteDataStreamInterface stream) throws IOException;
|
||||
}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TemporaryDataStream extends RandomAccessFileDataStream {
|
||||
|
||||
public TemporaryDataStream() throws IOException {
|
||||
this(new byte[0]);
|
||||
}
|
||||
|
||||
public TemporaryDataStream(byte[] data) throws IOException {
|
||||
super(File.createTempFile("tempdatastream", ".bin"));
|
||||
this.getFile().deleteOnExit();
|
||||
writeBytes(data);
|
||||
seek(0, SeekMode.SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
this.getFile().delete();
|
||||
} catch (Exception ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TemporaryDataStream extends RandomAccessFileDataStream {
|
||||
|
||||
public TemporaryDataStream() throws IOException {
|
||||
this(new byte[0]);
|
||||
}
|
||||
|
||||
public TemporaryDataStream(byte[] data) throws IOException {
|
||||
super(File.createTempFile("tempdatastream", ".bin"));
|
||||
this.getFile().deleteOnExit();
|
||||
writeBytes(data);
|
||||
seek(0, SeekMode.SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
this.getFile().delete();
|
||||
} catch (Exception ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface WriteDataStreamInterface extends AutoCloseable {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
public Long available();
|
||||
|
||||
public Long totalSize();
|
||||
|
||||
public long position();
|
||||
|
||||
public void setOlderOffsetToThisPos(long savedPos) throws IOException;
|
||||
|
||||
public void setOlderOffsetToThisPosCheck(long savedPos, long expected) throws IOException;
|
||||
|
||||
public boolean writeUI64(long val) throws IOException;
|
||||
|
||||
public boolean writeSI64(long val) throws IOException;
|
||||
|
||||
public boolean writeUI32(long val) throws IOException;
|
||||
|
||||
public boolean writeUI16(int val) throws IOException;
|
||||
|
||||
public boolean writeWChar(String val) throws IOException;
|
||||
|
||||
public void pad8bytes() throws IOException;
|
||||
|
||||
public boolean writeUI8(int val) throws IOException;
|
||||
|
||||
public void write(int val) throws IOException;
|
||||
|
||||
public void writeBytes(byte[] data) throws IOException;
|
||||
|
||||
public boolean writeFloat(float val) throws IOException;
|
||||
|
||||
public void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
public byte[] getAllBytes() throws IOException;
|
||||
|
||||
@Override
|
||||
public void close();
|
||||
|
||||
public void setIndexing(IggyIndexBuilder indexing);
|
||||
|
||||
public IggyIndexBuilder getIndexing();
|
||||
}
|
||||
package com.jpexs.decompiler.flash.iggy.streams;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface WriteDataStreamInterface extends AutoCloseable {
|
||||
|
||||
/**
|
||||
* Available bytes
|
||||
*
|
||||
* @return null if unknown, long value otherwise
|
||||
*/
|
||||
public Long available();
|
||||
|
||||
public Long totalSize();
|
||||
|
||||
public long position();
|
||||
|
||||
public void setOlderOffsetToThisPos(long savedPos) throws IOException;
|
||||
|
||||
public void setOlderOffsetToThisPosCheck(long savedPos, long expected) throws IOException;
|
||||
|
||||
public boolean writeUI64(long val) throws IOException;
|
||||
|
||||
public boolean writeSI64(long val) throws IOException;
|
||||
|
||||
public boolean writeUI32(long val) throws IOException;
|
||||
|
||||
public boolean writeUI16(int val) throws IOException;
|
||||
|
||||
public boolean writeWChar(String val) throws IOException;
|
||||
|
||||
public void pad8bytes() throws IOException;
|
||||
|
||||
public boolean writeUI8(int val) throws IOException;
|
||||
|
||||
public void write(int val) throws IOException;
|
||||
|
||||
public void writeBytes(byte[] data) throws IOException;
|
||||
|
||||
public boolean writeFloat(float val) throws IOException;
|
||||
|
||||
public void seek(long pos, SeekMode mode) throws IOException;
|
||||
|
||||
public byte[] getAllBytes() throws IOException;
|
||||
|
||||
@Override
|
||||
public void close();
|
||||
|
||||
public void setIndexing(IggyIndexBuilder indexing);
|
||||
|
||||
public IggyIndexBuilder getIndexing();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user