mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-01-03 19:13:26 -05:00
180 lines
4.4 KiB
C
180 lines
4.4 KiB
C
#ifndef _LZX_H
|
|
#define _LZX_H
|
|
|
|
/*
|
|
* Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
|
|
*
|
|
* 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 2 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* LZX decompression
|
|
*
|
|
*/
|
|
|
|
#include "huffman.h"
|
|
|
|
/** Number of aligned offset codes */
|
|
#define LZX_ALIGNOFFSET_CODES 8
|
|
|
|
/** Aligned offset code length (in bits) */
|
|
#define LZX_ALIGNOFFSET_BITS 3
|
|
|
|
/** Number of pretree codes */
|
|
#define LZX_PRETREE_CODES 20
|
|
|
|
/** Pretree code length (in bits) */
|
|
#define LZX_PRETREE_BITS 4
|
|
|
|
/** Number of literal main codes */
|
|
#define LZX_MAIN_LIT_CODES 256
|
|
|
|
/** Number of position slots */
|
|
#define LZX_POSITION_SLOTS 30
|
|
|
|
/** Number of main codes */
|
|
#define LZX_MAIN_CODES ( LZX_MAIN_LIT_CODES + ( 8 * LZX_POSITION_SLOTS ) )
|
|
|
|
/** Number of length codes */
|
|
#define LZX_LENGTH_CODES 249
|
|
|
|
/** Block type length (in bits) */
|
|
#define LZX_BLOCK_TYPE_BITS 3
|
|
|
|
/** Default block length */
|
|
#define LZX_DEFAULT_BLOCK_LEN 32768
|
|
|
|
/** Number of repeated offsets */
|
|
#define LZX_REPEATED_OFFSETS 3
|
|
|
|
/** Don't ask */
|
|
#define LZX_WIM_MAGIC_FILESIZE 12000000
|
|
|
|
/** Block types */
|
|
enum lzx_block_type {
|
|
/** Verbatim block */
|
|
LZX_BLOCK_VERBATIM = 1,
|
|
/** Aligned offset block */
|
|
LZX_BLOCK_ALIGNOFFSET = 2,
|
|
/** Uncompressed block */
|
|
LZX_BLOCK_UNCOMPRESSED = 3,
|
|
};
|
|
|
|
/** An LZX input stream */
|
|
struct lzx_input_stream {
|
|
/** Data */
|
|
const uint8_t *data;
|
|
/** Length */
|
|
size_t len;
|
|
/** Offset within stream */
|
|
size_t offset;
|
|
};
|
|
|
|
/** An LZX output stream */
|
|
struct lzx_output_stream {
|
|
/** Data, or NULL */
|
|
uint8_t *data;
|
|
/** Offset within stream */
|
|
size_t offset;
|
|
/** End of current block within stream */
|
|
size_t threshold;
|
|
};
|
|
|
|
/** LZX decompressor */
|
|
struct lzx {
|
|
/** Input stream */
|
|
struct lzx_input_stream input;
|
|
/** Output stream */
|
|
struct lzx_output_stream output;
|
|
/** Accumulator */
|
|
uint32_t accumulator;
|
|
/** Number of bits in accumulator */
|
|
unsigned int bits;
|
|
/** Block type */
|
|
enum lzx_block_type block_type;
|
|
/** Repeated offsets */
|
|
unsigned int repeated_offset[LZX_REPEATED_OFFSETS];
|
|
|
|
/** Aligned offset Huffman alphabet */
|
|
struct huffman_alphabet alignoffset;
|
|
/** Aligned offset raw symbols
|
|
*
|
|
* Must immediately follow the aligned offset Huffman
|
|
* alphabet.
|
|
*/
|
|
huffman_raw_symbol_t alignoffset_raw[LZX_ALIGNOFFSET_CODES];
|
|
/** Aligned offset code lengths */
|
|
uint8_t alignoffset_lengths[LZX_ALIGNOFFSET_CODES];
|
|
|
|
/** Pretree Huffman alphabet */
|
|
struct huffman_alphabet pretree;
|
|
/** Pretree raw symbols
|
|
*
|
|
* Must immediately follow the pretree Huffman alphabet.
|
|
*/
|
|
huffman_raw_symbol_t pretree_raw[LZX_PRETREE_CODES];
|
|
/** Preetree code lengths */
|
|
uint8_t pretree_lengths[LZX_PRETREE_CODES];
|
|
|
|
/** Main Huffman alphabet */
|
|
struct huffman_alphabet main;
|
|
/** Main raw symbols
|
|
*
|
|
* Must immediately follow the main Huffman alphabet.
|
|
*/
|
|
huffman_raw_symbol_t main_raw[LZX_MAIN_CODES];
|
|
/** Main code lengths */
|
|
struct {
|
|
/** Literals */
|
|
uint8_t literals[LZX_MAIN_LIT_CODES];
|
|
/** Remaining symbols */
|
|
uint8_t remainder[ LZX_MAIN_CODES - LZX_MAIN_LIT_CODES ];
|
|
} __attribute__ (( packed )) main_lengths;
|
|
|
|
/** Length Huffman alphabet */
|
|
struct huffman_alphabet length;
|
|
/** Length raw symbols
|
|
*
|
|
* Must immediately follow the length Huffman alphabet.
|
|
*/
|
|
huffman_raw_symbol_t length_raw[LZX_LENGTH_CODES];
|
|
/** Length code lengths */
|
|
uint8_t length_lengths[LZX_LENGTH_CODES];
|
|
};
|
|
|
|
/**
|
|
* Calculate number of footer bits for a given position slot
|
|
*
|
|
* @v position_slot Position slot
|
|
* @ret footer_bits Number of footer bits
|
|
*/
|
|
static inline unsigned int lzx_footer_bits ( unsigned int position_slot ) {
|
|
|
|
if ( position_slot < 2 ) {
|
|
return 0;
|
|
} else if ( position_slot < 38 ) {
|
|
return ( ( position_slot / 2 ) - 1 );
|
|
} else {
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
extern ssize_t lzx_decompress ( const void *data, size_t len, void *buf );
|
|
|
|
#endif /* _LZX_H */
|