mirror of
https://github.com/codestation/mhtools
synced 2024-12-05 01:19:28 +00:00
Major code refactoring: moved read/write functions in their own
class (EndianFixed), converted Decoder/Encoder classes into interfaces. Added support for extract/rebuild TMH containers. Added jar manifest.
This commit is contained in:
parent
5452659d0c
commit
fce2d43421
17 changed files with 739 additions and 185 deletions
|
@ -1,8 +1,11 @@
|
||||||
# translation_file, data_install_file, offset in the data install file where translation_file is found
|
# translation_file, data_install_file, offset in the data install file where translation_file is found
|
||||||
# Note: if you add files that doesn't exist in the data install just follow the
|
|
||||||
# format of the 0098
|
|
||||||
0017,0011,00204000
|
0017,0011,00204000
|
||||||
|
0043,0011,00310800
|
||||||
|
0045,0011,00316000
|
||||||
|
0046,0011,0031A800
|
||||||
|
0047,0011,0031F000
|
||||||
0098,NONE,FFFFFFFF
|
0098,NONE,FFFFFFFF
|
||||||
|
0222,0013,00143000
|
||||||
2813,0031,00280800
|
2813,0031,00280800
|
||||||
2814,0031,00284800
|
2814,0031,00284800
|
||||||
2816,0031,002AE000
|
2816,0031,002AE000
|
||||||
|
@ -20,3 +23,4 @@
|
||||||
3985,0032,00369000
|
3985,0032,00369000
|
||||||
3986,0033,00000000
|
3986,0033,00000000
|
||||||
3987,0033,00001000
|
3987,0033,00001000
|
||||||
|
3992,0033,000CC000
|
||||||
|
|
4
manifest.txt
Normal file
4
manifest.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Sealed: true
|
||||||
|
Main-Class: base.Mhtrans
|
||||||
|
|
|
@ -17,73 +17,6 @@
|
||||||
|
|
||||||
package base;
|
package base;
|
||||||
|
|
||||||
import java.io.EOFException;
|
public interface Decoder {
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.RandomAccessFile;
|
|
||||||
|
|
||||||
public abstract class Decoder {
|
|
||||||
|
|
||||||
public abstract void extract(String filename);
|
public abstract void extract(String filename);
|
||||||
|
|
||||||
/**
|
|
||||||
* The "readInt" function of java reads in BigEndian mode but we need
|
|
||||||
* LittleEndian so i made a custom function for that
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @return 8 byte integer in LittleEndian mode
|
|
||||||
* @throws IOException
|
|
||||||
* if any error occur while reading
|
|
||||||
*/
|
|
||||||
protected int readInt(RandomAccessFile file) throws IOException,
|
|
||||||
EOFException {
|
|
||||||
int ch1 = file.read();
|
|
||||||
int ch2 = file.read();
|
|
||||||
int ch3 = file.read();
|
|
||||||
int ch4 = file.read();
|
|
||||||
if ((ch1 | ch2 | ch3 | ch4) < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some hex-edited files have some extra zeros at the end of the strings
|
|
||||||
* so its better to skip them
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @throws IOException
|
|
||||||
* if any error occur while reading
|
|
||||||
*/
|
|
||||||
protected void advanceNext(RandomAccessFile file) throws IOException {
|
|
||||||
while (file.readByte() == 0) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
file.seek(file.getFilePointer() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The "readUTF8" function of java expects a different format of the
|
|
||||||
* string so i have to make a custom one
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @return string extracted from file
|
|
||||||
* @throws IOException
|
|
||||||
* if any error occur while reading
|
|
||||||
*/
|
|
||||||
protected String readString(RandomAccessFile file) throws IOException {
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
byte data = 0;
|
|
||||||
int counter = 0;
|
|
||||||
try {
|
|
||||||
do {
|
|
||||||
data = file.readByte();
|
|
||||||
buffer[counter++] = data;
|
|
||||||
} while (data != 0);
|
|
||||||
// checks if the string is a edited one
|
|
||||||
advanceNext(file);
|
|
||||||
} catch (EOFException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new String(buffer, 0, counter, "UTF-8");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,108 +17,6 @@
|
||||||
|
|
||||||
package base;
|
package base;
|
||||||
|
|
||||||
import java.io.EOFException;
|
public interface Encoder {
|
||||||
import java.io.IOException;
|
public abstract void compile(String filelist);
|
||||||
import java.io.RandomAccessFile;
|
|
||||||
|
|
||||||
public abstract class Encoder {
|
|
||||||
|
|
||||||
public abstract void compile(String filelist);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The "readUTF8" function of java expects a different format of
|
|
||||||
* the string so i have to make a custom one.
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @return string extracted from file
|
|
||||||
* @throws IOException
|
|
||||||
* if any error occur while reading
|
|
||||||
*/
|
|
||||||
protected String readString(RandomAccessFile file) throws IOException {
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
byte data = 0;
|
|
||||||
boolean eol = false;
|
|
||||||
int counter = 0;
|
|
||||||
try {
|
|
||||||
while (!eol) {
|
|
||||||
switch (data = file.readByte()) {
|
|
||||||
case '\n':
|
|
||||||
eol = true;
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
eol = true;
|
|
||||||
long cur = file.getFilePointer();
|
|
||||||
if (file.readByte() != '\n') {
|
|
||||||
file.seek(cur);
|
|
||||||
eol = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buffer[counter++] = data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (EOFException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new String(buffer, 0, counter, "UTF-8");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the file have the unicode BOM mark and skip it
|
|
||||||
* (thanks notepad grr..)
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @throws IOException
|
|
||||||
* if any error occur while reading
|
|
||||||
*/
|
|
||||||
protected void checkUnicodeBOM(RandomAccessFile file) throws IOException {
|
|
||||||
int a = file.readByte();
|
|
||||||
int b = file.readByte();
|
|
||||||
int c = file.readByte();
|
|
||||||
if (a != -17 || b != -69 || c != -65) {
|
|
||||||
file.seek(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The "writeInt" function of java writes in BigEndian mode but we need
|
|
||||||
* LittleEndian so i made a custom function for that
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @throws IOException
|
|
||||||
* if any error occur while writing
|
|
||||||
*/
|
|
||||||
protected void writeInt(RandomAccessFile file, int value)
|
|
||||||
throws IOException {
|
|
||||||
int ch1 = (byte) (value >>> 24);
|
|
||||||
int ch2 = (byte) (value >>> 16);
|
|
||||||
int ch3 = (byte) (value >>> 8);
|
|
||||||
int ch4 = (byte) value;
|
|
||||||
file.write(ch4);
|
|
||||||
file.write(ch3);
|
|
||||||
file.write(ch2);
|
|
||||||
file.write(ch1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The "readInt" function of java reads in BigEndian mode but we need
|
|
||||||
* LittleEndian so i made a custom function for that
|
|
||||||
*
|
|
||||||
* @param file
|
|
||||||
* @return 8 byte integer in LittleEndian mode
|
|
||||||
* @throws IOException
|
|
||||||
* if any error occur while reading
|
|
||||||
*/
|
|
||||||
protected int readInt(RandomAccessFile file) throws IOException,
|
|
||||||
EOFException {
|
|
||||||
int ch1 = file.read();
|
|
||||||
int ch2 = file.read();
|
|
||||||
int ch3 = file.read();
|
|
||||||
int ch4 = file.read();
|
|
||||||
if ((ch1 | ch2 | ch3 | ch4) < 0) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
95
src/base/EndianFixer.java
Normal file
95
src/base/EndianFixer.java
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/* MHTRANS v1.0
|
||||||
|
Copyright (C) 2011 Codestation
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package base;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
|
public abstract class EndianFixer {
|
||||||
|
|
||||||
|
protected int readInt(InputStream file) throws IOException, EOFException {
|
||||||
|
int ch1 = file.read();
|
||||||
|
int ch2 = file.read();
|
||||||
|
int ch3 = file.read();
|
||||||
|
int ch4 = file.read();
|
||||||
|
if ((ch1 | ch2 | ch3 | ch4) < 0) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int readInt(RandomAccessFile file) throws IOException, EOFException {
|
||||||
|
int ch1 = file.read();
|
||||||
|
int ch2 = file.read();
|
||||||
|
int ch3 = file.read();
|
||||||
|
int ch4 = file.read();
|
||||||
|
if ((ch1 | ch2 | ch3 | ch4) < 0) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int readShort(InputStream file) throws IOException, EOFException {
|
||||||
|
int ch1 = file.read();
|
||||||
|
int ch2 = file.read();
|
||||||
|
if ((ch1 | ch2) < 0) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
return (ch2 << 8) + (ch1 << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeShort(OutputStream file, int value) throws IOException {
|
||||||
|
int ch1 = (byte) (value >>> 8);
|
||||||
|
int ch2 = (byte) value;
|
||||||
|
file.write(ch2);
|
||||||
|
file.write(ch1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The "writeInt" function of java writes in BigEndian mode but we need
|
||||||
|
* LittleEndian so i made a custom function for that
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @throws IOException
|
||||||
|
* if any error occur while writing
|
||||||
|
*/
|
||||||
|
protected void writeInt(OutputStream file, int value) throws IOException {
|
||||||
|
int ch1 = (byte) (value >>> 24);
|
||||||
|
int ch2 = (byte) (value >>> 16);
|
||||||
|
int ch3 = (byte) (value >>> 8);
|
||||||
|
int ch4 = (byte) value;
|
||||||
|
file.write(ch4);
|
||||||
|
file.write(ch3);
|
||||||
|
file.write(ch2);
|
||||||
|
file.write(ch1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeInt(RandomAccessFile file, int value) throws IOException {
|
||||||
|
int ch1 = (byte) (value >>> 24);
|
||||||
|
int ch2 = (byte) (value >>> 16);
|
||||||
|
int ch3 = (byte) (value >>> 8);
|
||||||
|
int ch4 = (byte) value;
|
||||||
|
file.write(ch4);
|
||||||
|
file.write(ch3);
|
||||||
|
file.write(ch2);
|
||||||
|
file.write(ch1);
|
||||||
|
}
|
||||||
|
}
|
53
src/base/HelperDec.java
Normal file
53
src/base/HelperDec.java
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* MHTRANS v1.0
|
||||||
|
Copyright (C) 2011 Codestation
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package base;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
|
public abstract class HelperDec extends EndianFixer {
|
||||||
|
/**
|
||||||
|
* The "readUTF8" function of java expects a different format of the
|
||||||
|
* string so i have to make a custom one
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @return string extracted from file
|
||||||
|
* @throws IOException
|
||||||
|
* if any error occur while reading
|
||||||
|
*/
|
||||||
|
protected String readString(RandomAccessFile file) throws IOException {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
byte data = 0;
|
||||||
|
int counter = 0;
|
||||||
|
try {
|
||||||
|
do {
|
||||||
|
data = file.readByte();
|
||||||
|
buffer[counter++] = data;
|
||||||
|
} while (data != 0);
|
||||||
|
// checks if the string is a edited one
|
||||||
|
while (file.readByte() == 0) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
file.seek(file.getFilePointer() - 1);
|
||||||
|
} catch (EOFException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new String(buffer, 0, counter, "UTF-8");
|
||||||
|
}
|
||||||
|
}
|
71
src/base/HelperEnc.java
Normal file
71
src/base/HelperEnc.java
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/* MHTRANS v1.0
|
||||||
|
Copyright (C) 2011 Codestation
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package base;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
|
public abstract class HelperEnc extends EndianFixer {
|
||||||
|
protected String readString(RandomAccessFile file) throws IOException {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
byte data = 0;
|
||||||
|
boolean eol = false;
|
||||||
|
int counter = 0;
|
||||||
|
try {
|
||||||
|
while (!eol) {
|
||||||
|
switch (data = file.readByte()) {
|
||||||
|
case '\n':
|
||||||
|
eol = true;
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
eol = true;
|
||||||
|
long cur = file.getFilePointer();
|
||||||
|
if (file.readByte() != '\n') {
|
||||||
|
file.seek(cur);
|
||||||
|
eol = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buffer[counter++] = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (EOFException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new String(buffer, 0, counter, "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the file have the unicode BOM mark and skip it
|
||||||
|
* (thanks notepad grr..)
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* @throws IOException
|
||||||
|
* if any error occur while reading
|
||||||
|
*/
|
||||||
|
protected void checkUnicodeBOM(RandomAccessFile file) throws IOException {
|
||||||
|
int a = file.readByte();
|
||||||
|
int b = file.readByte();
|
||||||
|
int c = file.readByte();
|
||||||
|
if (a != -17 || b != -69 || c != -65) {
|
||||||
|
file.seek(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,9 +28,11 @@ import crypt.Encrypter;
|
||||||
import dec.ExtractPluginA;
|
import dec.ExtractPluginA;
|
||||||
import dec.ExtractPluginB;
|
import dec.ExtractPluginB;
|
||||||
import dec.ExtractPluginC;
|
import dec.ExtractPluginC;
|
||||||
|
import dec.ExtractPluginD;
|
||||||
import enc.RebuildPluginA;
|
import enc.RebuildPluginA;
|
||||||
import enc.RebuildPluginB;
|
import enc.RebuildPluginB;
|
||||||
import enc.RebuildPluginC;
|
import enc.RebuildPluginC;
|
||||||
|
import enc.RebuildPluginD;
|
||||||
|
|
||||||
public class Mhtrans {
|
public class Mhtrans {
|
||||||
|
|
||||||
|
@ -54,6 +56,9 @@ public class Mhtrans {
|
||||||
case 3:
|
case 3:
|
||||||
dec = new ExtractPluginC();
|
dec = new ExtractPluginC();
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
dec = new ExtractPluginD();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
System.err.println("Unknown decoder: " + decoder);
|
System.err.println("Unknown decoder: " + decoder);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
|
@ -62,11 +67,14 @@ public class Mhtrans {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void rebuild(String filename, String encoder) {
|
public static void rebuild(String filename, String encoder) {
|
||||||
String str = checkFile(filename + "/filelist.txt");
|
|
||||||
Encoder enc = null;
|
Encoder enc = null;
|
||||||
if (str == null)
|
|
||||||
System.exit(1);
|
|
||||||
int type = Integer.parseInt(encoder);
|
int type = Integer.parseInt(encoder);
|
||||||
|
if(type < 5) {
|
||||||
|
String str = checkFile(filename + "/filelist.txt");
|
||||||
|
if (str == null) {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
enc = new RebuildPluginA();
|
enc = new RebuildPluginA();
|
||||||
|
@ -80,6 +88,9 @@ public class Mhtrans {
|
||||||
case 3:
|
case 3:
|
||||||
enc = new RebuildPluginC();
|
enc = new RebuildPluginC();
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
enc = new RebuildPluginD();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
System.err.println("Unknown encoder: " + encoder);
|
System.err.println("Unknown encoder: " + encoder);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
|
|
|
@ -24,13 +24,14 @@ import java.io.PrintStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
import base.Decoder;
|
import base.Decoder;
|
||||||
|
import base.HelperDec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExtractPluginA v1.0 - 0016//0017/475x.bin language table extractor
|
* ExtractPluginA v1.0 - 0016//0017/475x.bin language table extractor
|
||||||
*
|
*
|
||||||
* @author Codestation
|
* @author Codestation
|
||||||
*/
|
*/
|
||||||
public class ExtractPluginA extends Decoder {
|
public class ExtractPluginA extends HelperDec implements Decoder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void extract(String filename) {
|
public void extract(String filename) {
|
||||||
|
|
|
@ -29,13 +29,14 @@ import java.io.RandomAccessFile;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import base.Decoder;
|
import base.Decoder;
|
||||||
|
import base.HelperDec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExtractPluginB v1.0 - 53xx.bin language table extractor
|
* ExtractPluginB v1.0 - 53xx.bin language table extractor
|
||||||
*
|
*
|
||||||
* @author Codestation
|
* @author Codestation
|
||||||
*/
|
*/
|
||||||
public class ExtractPluginB extends Decoder {
|
public class ExtractPluginB extends HelperDec implements Decoder {
|
||||||
|
|
||||||
private int mhp3_skip_bytes;
|
private int mhp3_skip_bytes;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ public class ExtractPluginB extends Decoder {
|
||||||
byte[] unknownData;
|
byte[] unknownData;
|
||||||
Vector<Integer> table_offset;
|
Vector<Integer> table_offset;
|
||||||
try {
|
try {
|
||||||
RandomAccessFile file = new RandomAccessFile(filename, "r");
|
RandomAccessFile file = new RandomAccessFile(filename,"r");
|
||||||
table_offset = new Vector<Integer>();
|
table_offset = new Vector<Integer>();
|
||||||
int pointer;
|
int pointer;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
@ -25,13 +25,14 @@ import java.io.RandomAccessFile;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import base.Decoder;
|
import base.Decoder;
|
||||||
|
import base.HelperDec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MHP2GDEC v1.0 - 537x.bin language table extractor
|
* MHP2GDEC v1.0 - 537x.bin language table extractor
|
||||||
*
|
*
|
||||||
* @author Codestation
|
* @author Codestation
|
||||||
*/
|
*/
|
||||||
public class ExtractPluginC extends Decoder {
|
public class ExtractPluginC extends HelperDec implements Decoder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void extract(String filename) {
|
public void extract(String filename) {
|
||||||
|
|
91
src/dec/ExtractPluginD.java
Normal file
91
src/dec/ExtractPluginD.java
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/* MHP2GDEC v1.0 - MH TMH image extractor
|
||||||
|
Copyright (C) 2011 Codestation
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dec;
|
||||||
|
|
||||||
|
import img.Gim;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import base.Decoder;
|
||||||
|
import base.EndianFixer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtractPluginD v1.0
|
||||||
|
*
|
||||||
|
* @author Codestation
|
||||||
|
*/
|
||||||
|
public class ExtractPluginD extends EndianFixer implements Decoder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void extract(String filename) {
|
||||||
|
try {
|
||||||
|
FileInputStream file = new FileInputStream(filename);
|
||||||
|
byte header_id[] = new byte[8];
|
||||||
|
file.read(header_id);
|
||||||
|
int header_gim_count = readInt(file);
|
||||||
|
file.skip(4);
|
||||||
|
//file.readInt(); //32 bit padding
|
||||||
|
for(int i = 0; i < header_gim_count; i++) {
|
||||||
|
Gim gim = new Gim();
|
||||||
|
gim.load(file);
|
||||||
|
int buffered_type = BufferedImage.TYPE_INT_ARGB;
|
||||||
|
BufferedImage bi = new BufferedImage(gim.getWidth(), gim.getHeight(), buffered_type);
|
||||||
|
bi.setRGB(0, 0, gim.getWidth(), gim.getHeight(), gim.getRGBarray(), 0, gim.getWidth());
|
||||||
|
String directory = filename.split("\\.")[0];
|
||||||
|
new File(directory).mkdir();
|
||||||
|
String fileformat;
|
||||||
|
String format;
|
||||||
|
if(gim.getDataType() == Gim.GIM_TYPE_PALETTE)
|
||||||
|
format = "palette";
|
||||||
|
else if(gim.getDataType() == Gim.GIM_TYPE_PIXELS)
|
||||||
|
format = "pixels";
|
||||||
|
else
|
||||||
|
format = "image";
|
||||||
|
String palette;
|
||||||
|
if(gim.getPaletteType() == Gim.RGBA8888) {
|
||||||
|
palette = "RGBA8888";
|
||||||
|
} else {
|
||||||
|
palette = "RGBA5551";
|
||||||
|
}
|
||||||
|
if(gim.isSupported()) {
|
||||||
|
fileformat = "png";
|
||||||
|
String fileout = String.format(directory + "/%03d", i) + "_" + format + "_" + palette + "." + fileformat;
|
||||||
|
System.out.println("Extracting " + fileout);
|
||||||
|
File out = new File(fileout);
|
||||||
|
out.delete();
|
||||||
|
ImageIO.write(bi,fileformat, out);
|
||||||
|
} else {
|
||||||
|
fileformat = "gim";
|
||||||
|
String fileout = String.format(directory + "/%03d", i) + "_" + format + "_" + palette + "." + fileformat;
|
||||||
|
FileOutputStream out = new FileOutputStream(fileout);
|
||||||
|
gim.write(out);
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
System.out.println("Finished!");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,13 +26,14 @@ import java.io.RandomAccessFile;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import base.Encoder;
|
import base.Encoder;
|
||||||
|
import base.HelperEnc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RebuildPluginA v2.0 - 0016/475x.bin language table rebuilder
|
* RebuildPluginA v2.0 - 0016/475x.bin language table rebuilder
|
||||||
*
|
*
|
||||||
* @author Codestation
|
* @author Codestation
|
||||||
*/
|
*/
|
||||||
public class RebuildPluginA extends Encoder {
|
public class RebuildPluginA extends HelperEnc implements Encoder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(String filepath) {
|
public void compile(String filepath) {
|
||||||
|
|
|
@ -32,13 +32,14 @@ import java.io.UnsupportedEncodingException;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import base.Encoder;
|
import base.Encoder;
|
||||||
|
import base.HelperEnc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RebuildPluginB v1.0 - 53xx.bin language table rebuilder
|
* RebuildPluginB v1.0 - 53xx.bin language table rebuilder
|
||||||
*
|
*
|
||||||
* @author codestation
|
* @author codestation
|
||||||
*/
|
*/
|
||||||
public class RebuildPluginB extends Encoder {
|
public class RebuildPluginB extends HelperEnc implements Encoder {
|
||||||
|
|
||||||
private int encoder = 0;
|
private int encoder = 0;
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,14 @@ import java.io.RandomAccessFile;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import base.Encoder;
|
import base.Encoder;
|
||||||
|
import base.HelperEnc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RebuildPluginC v1.0 - 537x.bin language table rebuilder
|
* RebuildPluginC v1.0 - 537x.bin language table rebuilder
|
||||||
*
|
*
|
||||||
* @author Codestation
|
* @author Codestation
|
||||||
*/
|
*/
|
||||||
public class RebuildPluginC extends Encoder {
|
public class RebuildPluginC extends HelperEnc implements Encoder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compile(String filepath) {
|
public void compile(String filepath) {
|
||||||
|
@ -121,7 +122,6 @@ public class RebuildPluginC extends Encoder {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in
|
||||||
|
|
105
src/enc/RebuildPluginD.java
Normal file
105
src/enc/RebuildPluginD.java
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/* MHP2GENC v1.0 - TMH image rebuilder
|
||||||
|
Copyright (C) 2008-2010 codestation
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package enc;
|
||||||
|
|
||||||
|
import img.Gim;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import base.Encoder;
|
||||||
|
import base.EndianFixer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RebuildPluginD v1.0
|
||||||
|
*
|
||||||
|
* @author Codestation
|
||||||
|
*/
|
||||||
|
public class RebuildPluginD extends EndianFixer implements Encoder {
|
||||||
|
|
||||||
|
private byte id[] = {0x2e, 0x54, 0x4d, 0x48, 0x30, 0x2e, 0x31, 0x34};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void compile(String filepath) {
|
||||||
|
try {
|
||||||
|
File dir = new File(filepath);
|
||||||
|
if(!dir.isDirectory()) {
|
||||||
|
System.err.println("Isn't a directory: " + filepath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File files[] = dir.listFiles();
|
||||||
|
Arrays.sort(files, new Comparator<File>() {
|
||||||
|
@Override
|
||||||
|
public int compare(File o1, File o2) {
|
||||||
|
return o1.getName().compareTo(o2.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(files.length > 0) {
|
||||||
|
FileOutputStream out = new FileOutputStream(dir.getName() + ".bin");
|
||||||
|
out.write(id);
|
||||||
|
writeInt(out, files.length);
|
||||||
|
writeInt(out, 0);
|
||||||
|
for(File file : files) {
|
||||||
|
System.out.println("Processing " + file.getName());
|
||||||
|
Gim gim = new Gim();
|
||||||
|
if(file.getName().endsWith(".gim")) {
|
||||||
|
FileInputStream in = new FileInputStream(file);
|
||||||
|
gim.load(in);
|
||||||
|
in.close();
|
||||||
|
} else {
|
||||||
|
BufferedImage img = ImageIO.read(file);
|
||||||
|
int[] rgbArray = new int[img.getWidth() * img.getHeight()];
|
||||||
|
img.getRGB(0, 0, img.getWidth(), img.getHeight(), rgbArray, 0, img.getWidth());
|
||||||
|
int type;
|
||||||
|
if(file.getName().contains("palette"))
|
||||||
|
type = Gim.GIM_TYPE_PALETTE;
|
||||||
|
else if(file.getName().contains("pixels"))
|
||||||
|
type = Gim.GIM_TYPE_PIXELS;
|
||||||
|
else
|
||||||
|
type = 0;
|
||||||
|
int depth;
|
||||||
|
if(file.getName().contains("RGBA8888"))
|
||||||
|
depth = Gim.RGBA8888;
|
||||||
|
else if(file.getName().contains("RGBA5551"))
|
||||||
|
depth = Gim.RGBA5551;
|
||||||
|
else
|
||||||
|
depth = 0;
|
||||||
|
gim.setRGBarray(img.getWidth(), img.getHeight(), rgbArray, type, depth);
|
||||||
|
}
|
||||||
|
gim.write(out);
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
} else {
|
||||||
|
System.err.println("Empty directory\n");
|
||||||
|
}
|
||||||
|
System.out.println("Finished!");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
System.out.println(e.toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
284
src/img/Gim.java
Normal file
284
src/img/Gim.java
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
package img;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import base.EndianFixer;
|
||||||
|
|
||||||
|
public class Gim extends EndianFixer {
|
||||||
|
|
||||||
|
public static final int RGBA8888 = 3;
|
||||||
|
public static final int RGBA5551 = 1;
|
||||||
|
public static final int GIM_TYPE_PIXELS = 4;
|
||||||
|
public static final int GIM_TYPE_PALETTE = 5;
|
||||||
|
public static final int HEADER_SIZE = 16;
|
||||||
|
public static final int BPP32_BYTE = 4;
|
||||||
|
public static final int BPP16_BYTE = 2;
|
||||||
|
public static final int BPP32 = 32;
|
||||||
|
public static final int BPP16 = 16;
|
||||||
|
|
||||||
|
private int size;
|
||||||
|
private int flags[] = new int[3];
|
||||||
|
private int data_size;
|
||||||
|
private int data_flags;
|
||||||
|
private int data_type;
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
private byte imagedata[];
|
||||||
|
private int palette_size;
|
||||||
|
private int palette_flags;
|
||||||
|
private int palette_type;
|
||||||
|
private int palette_count;
|
||||||
|
private byte palettedata[];
|
||||||
|
private int palettedata_count = 0;
|
||||||
|
private boolean loaded = false;
|
||||||
|
|
||||||
|
public void load(InputStream in) throws EOFException, IOException {
|
||||||
|
size = readInt(in);
|
||||||
|
flags[0] = readInt(in);
|
||||||
|
flags[1] = readInt(in);
|
||||||
|
flags[2] = readInt(in);
|
||||||
|
data_size = readInt(in);
|
||||||
|
data_flags = readInt(in);
|
||||||
|
data_type = readInt(in);
|
||||||
|
width = readShort(in);
|
||||||
|
height = readShort(in);
|
||||||
|
imagedata = new byte[data_size - 16];
|
||||||
|
in.read(imagedata);
|
||||||
|
palette_size = readInt(in);
|
||||||
|
palette_flags = readInt(in);
|
||||||
|
palette_type = readInt(in);
|
||||||
|
palette_count = readInt(in);
|
||||||
|
int palette_datasize = palette_count * (palette_type == RGBA8888 ? 4 : 2);
|
||||||
|
palettedata = new byte[palette_datasize];
|
||||||
|
in.read(palettedata);
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setRGBarray(int width, int height, int rgb[], int data_type, int palette_type) {
|
||||||
|
flags[0] = 0;
|
||||||
|
flags[1] = 1;
|
||||||
|
flags[2] = 1;
|
||||||
|
data_size = HEADER_SIZE;
|
||||||
|
data_flags = 1;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
palette_size = HEADER_SIZE;
|
||||||
|
this.palette_type = palette_type;
|
||||||
|
palette_flags = 2;
|
||||||
|
this.data_type = data_type;
|
||||||
|
if(data_type == GIM_TYPE_PIXELS) {
|
||||||
|
int palettesize = 16 * (palette_type == RGBA8888 ? 4 : 2);
|
||||||
|
palettedata = new byte[palettesize];
|
||||||
|
data_size += (width / 2) * height;
|
||||||
|
imagedata = new byte[data_size - HEADER_SIZE];
|
||||||
|
palette_count = fill_to_palette(rgb);
|
||||||
|
palette_count = 16;
|
||||||
|
palette_size += palettesize;
|
||||||
|
size = data_size + palette_size + HEADER_SIZE;
|
||||||
|
} else if(data_type == GIM_TYPE_PALETTE) {
|
||||||
|
int palettesize = 256 * (palette_type == RGBA8888 ? 4 : 2);
|
||||||
|
palettedata = new byte[palettesize];
|
||||||
|
data_size += width * height;
|
||||||
|
imagedata = new byte[data_size - HEADER_SIZE];
|
||||||
|
palette_count = fill_to_palette(rgb);
|
||||||
|
palette_count = 256;
|
||||||
|
palette_size += palettesize;
|
||||||
|
size = data_size + palette_size + HEADER_SIZE;
|
||||||
|
} else {
|
||||||
|
loaded = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
loaded = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[]getRGBarray() {
|
||||||
|
if(!loaded)
|
||||||
|
return null;
|
||||||
|
int dsx = width;
|
||||||
|
int dsy = height;
|
||||||
|
int mod = (data_type == GIM_TYPE_PALETTE ? BPP16 : BPP32);
|
||||||
|
int colorsize = palette_type == RGBA8888 ? BPP32_BYTE : BPP16_BYTE;
|
||||||
|
dsx /= mod;
|
||||||
|
dsy /= 8;
|
||||||
|
int counter = 0;
|
||||||
|
int bitmapbuffer[] = new int[width * height];
|
||||||
|
boolean flip = false;
|
||||||
|
for (int sy = 0; sy < dsy; sy++) {
|
||||||
|
for (int sx = 0; sx < dsx; sx++) {
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
for (int x = 0; x < mod; x++) {
|
||||||
|
int pos = (int)(imagedata[counter] & 0xFF);
|
||||||
|
if(data_type == GIM_TYPE_PIXELS) {
|
||||||
|
if(flip)
|
||||||
|
pos = pos >> 4;
|
||||||
|
else
|
||||||
|
pos = pos & 0xF;
|
||||||
|
}
|
||||||
|
int off = (((sy * 8) + y) * width + ((sx * mod) + x));
|
||||||
|
int rgb = get_color(pos * colorsize);
|
||||||
|
bitmapbuffer[off] = rgb;
|
||||||
|
if(data_type == GIM_TYPE_PIXELS) {
|
||||||
|
if(flip) {
|
||||||
|
counter++;
|
||||||
|
flip = false;
|
||||||
|
} else {
|
||||||
|
flip = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bitmapbuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean write(OutputStream out)throws IOException {
|
||||||
|
if(!loaded)
|
||||||
|
return false;
|
||||||
|
writeInt(out, size);
|
||||||
|
writeInt(out, flags[0]);
|
||||||
|
writeInt(out, flags[1]);
|
||||||
|
writeInt(out, flags[2]);
|
||||||
|
writeInt(out, data_size);
|
||||||
|
writeInt(out, data_flags);
|
||||||
|
writeInt(out, data_type);
|
||||||
|
writeShort(out, width);
|
||||||
|
writeShort(out, height);
|
||||||
|
out.write(imagedata);
|
||||||
|
writeInt(out, palette_size);
|
||||||
|
writeInt(out, palette_flags);
|
||||||
|
writeInt(out, palette_type);
|
||||||
|
writeInt(out, palette_count);
|
||||||
|
out.write(palettedata);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int fill_to_palette(int rgb[]) {
|
||||||
|
int mod = (data_type == GIM_TYPE_PALETTE ? BPP16 : BPP32);
|
||||||
|
int dsx = width / mod;
|
||||||
|
int dsy = height / 8;
|
||||||
|
boolean flip = false;
|
||||||
|
int counter = 0;
|
||||||
|
palettedata_count = 0;
|
||||||
|
for (int sy = 0; sy < dsy; sy++) {
|
||||||
|
for (int sx = 0; sx < dsx; sx++) {
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
for (int x = 0; x < mod; x++) {
|
||||||
|
int off = (((sy * 8) + y) * width + ((sx * mod) + x));
|
||||||
|
if(data_type == GIM_TYPE_PALETTE && palettedata_count > 256 ||
|
||||||
|
data_type == GIM_TYPE_PIXELS && palettedata_count > 16) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int color = rgb[off];
|
||||||
|
int index = set_unique_color(color);
|
||||||
|
if(data_type == GIM_TYPE_PIXELS) {
|
||||||
|
if(flip) {
|
||||||
|
imagedata[counter] |= (byte) (index << 4);
|
||||||
|
counter++;
|
||||||
|
flip = false;
|
||||||
|
} else {
|
||||||
|
imagedata[counter] = (byte) (index & 0xF);
|
||||||
|
flip = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
imagedata[counter] = (byte) index;
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return palette_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void set_color(int color, int offset) {
|
||||||
|
int A = (color >> 24) & 0xFF;
|
||||||
|
int R = (color >> 16) & 0xFF;
|
||||||
|
int G = (color >> 8) & 0xFF;
|
||||||
|
int B = color & 0xFF;
|
||||||
|
if(palette_type == RGBA8888) {
|
||||||
|
palettedata[offset + 2] = (byte) B;
|
||||||
|
palettedata[offset + 1] = (byte) G;
|
||||||
|
palettedata[offset + 0] = (byte) R;
|
||||||
|
palettedata[offset + 3] = (byte) A;
|
||||||
|
} else {
|
||||||
|
A = A == 0 ? 0 : 1;
|
||||||
|
R = R >> 3;
|
||||||
|
G = G >> 3;
|
||||||
|
B = B >> 3;
|
||||||
|
color = R;
|
||||||
|
color |= G << 5;
|
||||||
|
color |= B << 10;
|
||||||
|
color |= A << 15;
|
||||||
|
palettedata[offset+1] = (byte) (color >> 8 & 0xFF);
|
||||||
|
palettedata[offset+0] = (byte) (color & 0xFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int set_unique_color(int color) {
|
||||||
|
int i = 0;
|
||||||
|
while(i < palettedata_count) {
|
||||||
|
if(color == get_color(i * (palette_type == RGBA8888 ? 4 : 2))) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
set_color(color, i * (palette_type == RGBA8888 ? 4 : 2));
|
||||||
|
palettedata_count = i + 1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int get_color(int offset) {
|
||||||
|
int A, R, G, B;
|
||||||
|
if(palette_type == RGBA8888) {
|
||||||
|
B = (int)palettedata[offset + 2] & 0xFF;
|
||||||
|
G = (int)palettedata[offset + 1] & 0xFF;
|
||||||
|
R = (int)palettedata[offset + 0] & 0xFF;
|
||||||
|
A = (int)palettedata[offset + 3] & 0xFF;
|
||||||
|
} else {
|
||||||
|
int color = (((int)(palettedata[offset+1]) << 8) & 0xFF00);
|
||||||
|
color |=((int)(palettedata[offset]) & 0xFF);
|
||||||
|
R = color & 0x1F;
|
||||||
|
G = (color >> 5) & 0x1F;
|
||||||
|
B = (color >> 10) & 0x1F;
|
||||||
|
A = (color >> 15) & 0x1;
|
||||||
|
R = (R << 3) | (R >> 2);
|
||||||
|
G = (G << 3) | (G >> 2);
|
||||||
|
B = (B << 3) | (B >> 2);
|
||||||
|
A = A == 0 ? 0 : 255;
|
||||||
|
}
|
||||||
|
int res = ((A << 24) + (R << 16) + (G << 8) + B);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDataType() {
|
||||||
|
return data_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPaletteType() {
|
||||||
|
return palette_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPaletteCount() {
|
||||||
|
return palette_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSupported() {
|
||||||
|
return (data_type == GIM_TYPE_PIXELS && palette_count <=16) ||
|
||||||
|
(data_type == GIM_TYPE_PALETTE && palette_count <= 256);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue