howfie wrote:somebody said xbox and ps3 files are identical just different endian, so i'm assuming zlib. post a screenshot of the hex where the compressed data starts. the PC files contain the zlib prefix 78DA so i don't think the xbox one will have the missing prefix. if it's a different compression i would first try one of the LZOs or the xmemcompress as they are fairly common to the xbox.
The compressed data in the xbox360 file does not contain a regular zlib header. It may have some kind of truncated zlib header though.
I've yet to try XMemDecompress(), but was thinking about trying it next.
Here are some of the methods I've tried in C#....
Props to all who have been working on this.
This one attempts to use an ICSharpZipLib Inflater. I get the same results as Gh0stBlade's v1.2 bms script on some files.
Code: Select all
public byte[] Inflate(byte[] inputData)
{
Inflater inflater = new Inflater(true);
using (var inputStream = new MemoryStream(inputData))
using (var ms = new MemoryStream())
{
var inputBuffer = new byte[4096];
var outputBuffer = new byte[4096];
while (inputStream.Position < inputData.Length)
{
var read = inputStream.Read(inputBuffer, 0, inputBuffer.Length);
inflater.SetInput(inputBuffer, 11, (read - 11));
while (inflater.IsNeedingInput == false)
{
var written = inflater.Inflate(outputBuffer, 0, outputBuffer.Length);
if (written == 0)
break;
ms.Write(outputBuffer, 0, written);
}
if (inflater.IsFinished == true)
break;
}
inflater.Reset();
return ms.ToArray();
}
}
The next one I pulled from Rick's Volition source. This method was returning an error something like bad header checksum, as I think it attempts to decompress using a normal zlib header.
Code: Select all
public byte[] ZLibDecompress(byte[] zLibCompressedBuffer)
{
byte[] resBuffer = null;
MemoryStream mInStream = new MemoryStream(zLibCompressedBuffer);
MemoryStream mOutStream = new MemoryStream(zLibCompressedBuffer.Length);
InflaterInputStream infStream = new InflaterInputStream(mInStream);
mInStream.Position = 0;
try
{
byte[] tmpBuffer = new byte[zLibCompressedBuffer.Length];
int read = 0;
do
{
read = infStream.Read(tmpBuffer, 0, tmpBuffer.Length);
if (read > 0)
mOutStream.Write(tmpBuffer, 0, read);
} while (read > 0);
resBuffer = mOutStream.ToArray();
}
finally
{
infStream.Close();
mInStream.Close();
mOutStream.Close();
}
return resBuffer;
}
The next one I tried is pulled from the SR4 VPP source posted above. This one returned similar errors (broken uncompressed block, unknown block type).
Code: Select all
public static byte[] Decompress(byte[] data)
{
var compressedStream = new MemoryStream(data);
var zipStream = new DeflateStream(compressedStream, CompressionMode.Decompress);
var resultStream = new MemoryStream();
var buffer = new byte[4096];
int read;
while ((read = zipStream.Read(buffer, 0, buffer.Length)) > 0)
resultStream.Write(buffer, 0, read);
return resultStream.ToArray();
}
Another one I tried is based on the ThomasJepp source posted above. This code specifically tests jump_sm.xtbl from TU1 on the xbox.
Code: Select all
byte[] fileTmp = File.ReadAllBytes(this.textBox1.Text);
Stream stream = File.OpenRead(this.textBox1.Text);
Stream DataStream;
stream.Read(fileTmp, 0, fileTmp.Length);
FileStream fs = new FileStream(currentPath + "\\" + Path.GetFileNameWithoutExtension(currentFile) + ".test.bin", FileMode.Create, FileAccess.Write);
using (MemoryStream tempStream = new MemoryStream(fileTmp))
{
using (Stream s = new ZlibStream(tempStream, CompressionMode.Decompress, true))
{
byte[] uncompressedData = new byte[64411];
s.Read(uncompressedData, 0, uncompressedData.Length);
DataStream = new MemoryStream(uncompressedData);
DataStream.CopyTo(fs);
}
}
fs.Close();
I also tried some other quick tests using a few different methods. Again with various errors.
Code: Select all
---------------------------------------------------------------------------------------------------
FileStream s1 = new FileStream(this.textBox1.Text, FileMode.Open, FileAccess.Read);
FileStream sw1 = new FileStream(this.textBox1.Text + ".test.bin", FileMode.Create, FileAccess.Write);
DeflateStream ds1 = new DeflateStream(s1, CompressionMode.Decompress);
ds1.CopyTo(sw1);
ds1.Dispose();
s1.Close();
sw1.Close();
---------------------------------------------------------------------------------------------------
byte[] dst = new byte[UInt32.Parse(vx2SectionTable[(int)i][2])];
Inflater ifr = new Inflater(true);
ifr.SetInput(fileTmp, 8, (fileTmp.Length - 8));
ifr.Inflate(dst, 0, dst.Length);
File.WriteAllBytes(currentPath + "\\" + Path.GetFileNameWithoutExtension(currentFile) + "_compressed_files\\decompressed\\" + vx2NamesTable[(int)i], dst);
ifr.Reset();
---------------------------------------------------------------------------------------------------
byte[] dst = new byte[UInt32.Parse(vx2SectionTable[(int)i][2])];
[DllImport("zlib1.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int uncompress(byte[] dest, ref uint destLen, byte[] source, uint sourceLen);
uint dstSize = UInt32.Parse(vx2SectionTable[(int)i][2]);
uint srcSize = UInt32.Parse(vx2SectionTable[(int)i][3]);
uncompress(dst, ref dstSize, fileTmp, (uint)srcSize);
File.WriteAllBytes(currentPath + "\\" + Path.GetFileNameWithoutExtension(currentFile) + "_compressed_files\\decompressed\\" + vx2NamesTable[(int)i], dst);
---------------------------------------------------------------------------------------------------
I'm not using the alignment or compression flags that look like they are there in the header sections. Has anyone made any progress on inflating?
Its probably something simple that I'm not doing.