mirror of
https://github.com/blacktop/ipsw.git
synced 2026-06-07 12:27:36 +00:00
207 lines
7.1 KiB
Plaintext
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;
|
|
}
|
|
} |