mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
(Unity): decompress LZMA blocks.
This commit is contained in:
@@ -28,6 +28,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using GameRes.Compression;
|
using GameRes.Compression;
|
||||||
|
using LZMA = SevenZip.Compression.LZMA;
|
||||||
|
|
||||||
namespace GameRes.Formats.Unity
|
namespace GameRes.Formats.Unity
|
||||||
{
|
{
|
||||||
@@ -97,20 +98,45 @@ namespace GameRes.Formats.Unity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] PrepareBuffer (uint length)
|
||||||
|
{
|
||||||
|
if (null == m_buffer || length > m_buffer.Length)
|
||||||
|
m_buffer = new byte[length];
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void ReadCompressedSegment (BundleSegment segment)
|
void ReadCompressedSegment (BundleSegment segment)
|
||||||
{
|
{
|
||||||
m_input.Position = segment.Offset;
|
m_input.Position = segment.Offset;
|
||||||
|
int method = segment.Compression & 0x3F;
|
||||||
|
if (1 == method)
|
||||||
|
{
|
||||||
|
m_buffer_len = LzmaDecompressBlock (segment.PackedSize, segment.UnpackedSize);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (null == m_packed || segment.PackedSize > m_packed.Length)
|
if (null == m_packed || segment.PackedSize > m_packed.Length)
|
||||||
m_packed = new byte[segment.PackedSize];
|
m_packed = new byte[segment.PackedSize];
|
||||||
int packed_size = m_input.Read (m_packed, 0, (int)segment.PackedSize);
|
int packed_size = m_input.Read (m_packed, 0, (int)segment.PackedSize);
|
||||||
if (null == m_buffer || segment.UnpackedSize > m_buffer.Length)
|
var output = PrepareBuffer (segment.UnpackedSize);
|
||||||
m_buffer = new byte[segment.UnpackedSize];
|
if (3 == method)
|
||||||
if (3 == segment.Compression)
|
m_buffer_len = Lz4Compressor.DecompressBlock (m_packed, packed_size, output, (int)segment.UnpackedSize);
|
||||||
m_buffer_len = Lz4Compressor.DecompressBlock (m_packed, packed_size, m_buffer, (int)segment.UnpackedSize);
|
|
||||||
else
|
else
|
||||||
throw new NotImplementedException ("Not supported Unity asset bundle compression.");
|
throw new NotImplementedException ("Not supported Unity asset bundle compression.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LzmaDecompressBlock (uint packed_size, uint unpacked_size)
|
||||||
|
{
|
||||||
|
var decoder = new LZMA.Decoder();
|
||||||
|
var props = m_input.ReadBytes (5);
|
||||||
|
decoder.SetDecoderProperties (props);
|
||||||
|
var buffer = PrepareBuffer (unpacked_size);
|
||||||
|
using (var output = new MemoryStream (buffer))
|
||||||
|
{
|
||||||
|
decoder.Code (m_input, output, packed_size-5, unpacked_size, null);
|
||||||
|
return (int)output.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ReadFromSegment (BundleSegment segment, byte[] buffer, int offset, int count)
|
int ReadFromSegment (BundleSegment segment, byte[] buffer, int offset, int count)
|
||||||
{
|
{
|
||||||
Debug.Assert (m_position >= segment.UnpackedOffset && m_position <= segment.UnpackedOffset + segment.UnpackedSize);
|
Debug.Assert (m_position >= segment.UnpackedOffset && m_position <= segment.UnpackedOffset + segment.UnpackedSize);
|
||||||
|
|||||||
Reference in New Issue
Block a user