Files
ipsw/hack/extras/LZFSE.bt
2020-01-25 09:49:37 -05:00

207 lines
7.1 KiB
Plaintext

//------------------------------------------------
//--- 010 Editor v9.0.1 Binary Template
//
// File: LZFSE.bt
// Authors: blacktop
// Version: 1.0
// Purpose: Parse LZFSE archive files.
// Category: Archive
// File Mask:
// ID Bytes: 62 76 78 6E //bvxn
// History:
//------------------------------------------------
#define LZFSE_NO_BLOCK_MAGIC 0x00000000 // 0 (invalid)
#define LZFSE_ENDOFSTREAM_BLOCK_MAGIC 0x24787662 // bvx$ (end of stream)
#define LZFSE_UNCOMPRESSED_BLOCK_MAGIC 0x2d787662 // bvx- (raw data)
#define LZFSE_COMPRESSEDV1_BLOCK_MAGIC 0x31787662 // bvx1 (lzfse compressed, uncompressed tables)
#define LZFSE_COMPRESSEDV2_BLOCK_MAGIC 0x32787662 // bvx2 (lzfse compressed, compressed tables)
#define LZFSE_COMPRESSEDLZVN_BLOCK_MAGIC 0x6e787662 // bvxn (lzvn compressed)
#define LZFSE_ENCODE_L_SYMBOLS 20
#define LZFSE_ENCODE_M_SYMBOLS 20
#define LZFSE_ENCODE_D_SYMBOLS 64
#define LZFSE_ENCODE_LITERAL_SYMBOLS 256
#define LZFSE_ENCODE_L_STATES 64
#define LZFSE_ENCODE_M_STATES 64
#define LZFSE_ENCODE_D_STATES 256
#define LZFSE_ENCODE_LITERAL_STATES 1024
#define LZFSE_MATCHES_PER_BLOCK 10000
typedef struct {
// Magic number, always LZFSE_COMPRESSEDV1_BLOCK_MAGIC.
char magic[4] <bgcolor=cBlue>;
// Number of decoded (output) bytes in block.
uint n_raw_bytes;
// Number of encoded (source) bytes in block.
uint n_payload_bytes;
// Number of literal bytes output by block (*not* the number of literals).
uint n_literals;
// Number of matches in block (which is also the number of literals).
uint n_matches;
// Number of bytes used to encode literals.
uint n_literal_payload_bytes;
// Number of bytes used to encode matches.
uint n_lmd_payload_bytes;
// Final encoder states for the block, which will be the initial states for
// the decoder:
// Final accum_nbits for literals stream.
int literal_bits;
// There are four interleaved streams of literals, so there are four final
// states.
ushort literal_state[4];
// accum_nbits for the l, m, d stream.
int lmd_bits;
// Final L (literal length) state.
ushort l_state;
// Final M (match length) state.
ushort m_state;
// Final D (match distance) state.
ushort d_state;
// Normalized frequency tables for each stream. Sum of values in each
// array is the number of states.
ushort l_freq[LZFSE_ENCODE_L_SYMBOLS];
ushort m_freq[LZFSE_ENCODE_M_SYMBOLS];
ushort d_freq[LZFSE_ENCODE_D_SYMBOLS];
ushort literal_freq[LZFSE_ENCODE_LITERAL_SYMBOLS];
} lzfse_compressed_block_header_v1;
typedef struct {
BitfieldDisablePadding();
BitfieldLeftToRight();
// 0 20 n_literals
uint n_literals : 20;
// 20 20 n_literal_payload_bytes
uint n_literal_payload_bytes : 20;
// 40 20 n_matches
uint n_matches : 20;
// 60 3
int literal_bits : 3;
// 63 1 --- unused ---
uint : 1;
} field1 <comment="uint64">;
typedef struct {
// 0 10 literal_state[0]
ushort literal_state0 : 10;
// 10 10 literal_state[1]
ushort literal_state1 : 10;
// 20 10 literal_state[2]
ushort literal_state2 : 10;
// 30 10 literal_state[3]
ushort literal_state3 : 10;
// 40 20 n_lmd_payload_bytes
uint n_lmd_payload_bytes : 20;
// 60 3 lmd_bits
int lmd_bits : 3;
// 63 1 --- unused ---
uint : 1;
} field2 <comment="uint64">;
typedef struct {
BitfieldDisablePadding();
BitfieldLeftToRight();
// 0 32 header_size (total header size in bytes; this does not
// correspond to a field in the uncompressed header version,
// but is required; we wouldn't know the size of the
// compresssed header otherwise.
uint header_size : 32;
// 32 10 l_state
ushort l_state : 10;
// 42 10 m_state
ushort m_state : 10;
// 52 10 d_state
ushort d_state : 10;
// 62 2 --- unused ---
uint : 2;
} field3 <comment="uint64">;
typedef struct {
// Magic number, always LZFSE_COMPRESSEDV2_BLOCK_MAGIC.
char magic[4] <bgcolor=cBlue>;
// Number of decoded (output) bytes in block.
uint n_raw_bytes;
// The fields n_payload_bytes ... d_state from the
// lzfse_compressed_block_header_v1 object are packed into three 64-bit
// fields in the compressed header, as follows:
//
// offset bits value
// 0 20 n_literals
// 20 20 n_literal_payload_bytes
// 40 20 n_matches
// 60 3 literal_bits
// 63 1 --- unused ---
//
// 0 10 literal_state[0]
// 10 10 literal_state[1]
// 20 10 literal_state[2]
// 30 10 literal_state[3]
// 40 20 n_lmd_payload_bytes
// 60 3 lmd_bits
// 63 1 --- unused ---
//
// 0 32 header_size (total header size in bytes; this does not
// correspond to a field in the uncompressed header version,
// but is required; we wouldn't know the size of the
// compresssed header otherwise.
// 32 10 l_state
// 42 10 m_state
// 52 10 d_state
// 62 2 --- unused ---
field1 Characteristics <bgcolor=cLtGray>;
field2 Characteristics2 <bgcolor=cLtGray>;
field3 Characteristics3 <bgcolor=cLtGray>;
// Variable size freq tables, using a Huffman-style fixed encoding.
// Size allocated here is an upper bound (all values stored on 16 bits).
uchar freq[2 * (LZFSE_ENCODE_L_SYMBOLS + LZFSE_ENCODE_M_SYMBOLS +
LZFSE_ENCODE_D_SYMBOLS + LZFSE_ENCODE_LITERAL_SYMBOLS)] <bgcolor=cGray>;
//Printf( "Characteristics.n_literal_payload_bytes='%d'\n", Characteristics.n_literal_payload_bytes );
uchar payload[Characteristics.n_literal_payload_bytes + Characteristics2.n_lmd_payload_bytes] <bgcolor=cLtGray>;
char endMagic[4] <bgcolor=cLtBlue>;
} lzfse_compressed_block_header_v2;
typedef struct {
char magic[4] <bgcolor=cBlue>;
uint n_raw_bytes;
uint n_payload_bytes;
uchar payload[n_payload_bytes] <bgcolor=cLtGray>;
char endMagic[4] <bgcolor=cLtBlue>;
} LZVN_COMPRESSED_BLOCK_HEADER;
//--------------------------------------------
// Define the file
local uint magic;
LittleEndian();
while( !FEof() )
{
// Read a magic
magic = ReadUInt( FTell() );
// Read data depending upon magic - should start with 'bvxn'.
// Note that when duplicate variables are defined, they
// are made into an array (see 'Using Templates and Structs'
// in the help file).
if( magic == LZFSE_COMPRESSEDLZVN_BLOCK_MAGIC )
{
//SetBackColor( cLtGray );
LZVN_COMPRESSED_BLOCK_HEADER record;
}
else if( magic == LZFSE_COMPRESSEDV1_BLOCK_MAGIC )
{
SetBackColor( cLtGreen );
lzfse_compressed_block_header_v1 lzfse_c1;
}
else if( magic == LZFSE_COMPRESSEDV2_BLOCK_MAGIC )
{
SetBackColor( cLtGreen );
lzfse_compressed_block_header_v2 lzfse_c2;
}
else
{
Warning( "Unknown LZFSE magic encountered. Template stopped." );
return -1;
}
}