You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Ventoy/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.h

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 */