unleashed-firmware/lib/toolbox/compress.h
hedger fcbcb6b5a8
Updater: resource compression (#3716)
* toolbox: compress: moved decompressor implementation to separate func
* toolbox: compress: callback-based api; cli: storage unpack command
* toolbox: compress: separate r/w contexts for stream api
* targets: f18: sync API
* compress: naming fixes & cleanup
* toolbox: compress: using hs buffer size for stream buffers
* toolbox: tar: heatshrink stream mode
* toolbox: compress: docs & small cleanup
* toolbox: tar: header support for .hs; updater: now uses .hs for resources; .hs.tar: now rewindable
* toolbox: compress: fixed hs stream tail handling
* updater: reworked progress for resources cleanup; rebalanced stage weights
* updater: single-pass decompression; scripts: print resources compression ratio
* updater: fixed warnings
* toolbox: tar: doxygen
* docs: update
* docs: info or tarhs format; scripts: added standalone compression/decompression tool for heatshrink-formatted streams
* scripts: tarhs: fixed parameter handling
* cli: storage extract command; toolbox: tar: guess type based on extension
* unit_tests: added test for streamed raw hs decompressor `compress_decode_streamed`
* unit_tests: compress: added extraction test for .tar.hs
* rpc: autodetect compressed archives
* scripts: minor cleanup of common parts
* scripts: update: now using in-memory intermediate tar stream
* scripts: added hs.py wrapper for heatshrink-related ops (single object and directory-as-tar compression)
* scripts: naming fixes
* Toolbox: export compress_config_heatshrink_default as const symbol
* Toolbox: fix various types naming
* Toolbox: more of types naming fixes
* Toolbox: use size_t in compress io callbacks and structures
* UnitTests: update to match new compress API
* Toolbox: proper path_extract_extension usage

Co-authored-by: あく <alleteam@gmail.com>
2024-06-30 11:38:48 +01:00

220 lines
6.4 KiB
C

/**
* @file compress.h
* LZSS based compression HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Compress Icon control structure */
typedef struct CompressIcon CompressIcon;
/** Initialize icon compressor
*
* @param[in] decode_buf_size The icon buffer size for decoding. Ensure that
* it's big enough for any icons that you are
* planning to decode with it.
*
* @return Compress Icon instance
*/
CompressIcon* compress_icon_alloc(size_t decode_buf_size);
/** Free icon compressor
*
* @param instance The Compress Icon instance
*/
void compress_icon_free(CompressIcon* instance);
/** Decompress icon
*
* @warning output pointer set by this function is valid till next
* `compress_icon_decode` or `compress_icon_free` call
*
* @param instance The Compress Icon instance
* @param icon_data pointer to icon data.
* @param[in] output pointer to decoded buffer pointer. Data in buffer is
* valid till next call. If icon data was not compressed,
* pointer within icon_data is returned
*/
void compress_icon_decode(CompressIcon* instance, const uint8_t* icon_data, uint8_t** output);
//////////////////////////////////////////////////////////////////////////
/** Compress control structure */
typedef struct Compress Compress;
/** Supported compression types */
typedef enum {
CompressTypeHeatshrink = 0,
} CompressType;
/** Configuration for heatshrink compression */
typedef struct {
uint16_t window_sz2;
uint16_t lookahead_sz2;
uint16_t input_buffer_sz;
} CompressConfigHeatshrink;
/** Default configuration for heatshrink compression. Used for image assets. */
extern const CompressConfigHeatshrink compress_config_heatshrink_default;
/** Allocate encoder and decoder
*
* @param type Compression type
* @param[in] config Configuration for compression, specific to type
*
* @return Compress instance
*/
Compress* compress_alloc(CompressType type, const void* config);
/** Free encoder and decoder
*
* @param compress Compress instance
*/
void compress_free(Compress* compress);
/** Encode data
*
* @param compress Compress instance
* @param data_in pointer to input data
* @param data_in_size size of input data
* @param data_out maximum size of output data
* @param[in] data_out_size The data out size
* @param data_res_size pointer to result output data size
*
* @note Prepends compressed stream with a header. If data is not compressible,
* it will be stored as is after the header.
* @return true on success
*/
bool compress_encode(
Compress* compress,
uint8_t* data_in,
size_t data_in_size,
uint8_t* data_out,
size_t data_out_size,
size_t* data_res_size);
/** Decode data
*
* @param compress Compress instance
* @param data_in pointer to input data
* @param data_in_size size of input data
* @param data_out maximum size of output data
* @param[in] data_out_size The data out size
* @param data_res_size pointer to result output data size
*
* @note Expects compressed stream with a header, as produced by `compress_encode`.
* @return true on success
*/
bool compress_decode(
Compress* compress,
uint8_t* data_in,
size_t data_in_size,
uint8_t* data_out,
size_t data_out_size,
size_t* data_res_size);
/** I/O callback for streamed compression/decompression
*
* @param context user context
* @param buffer buffer to read/write
* @param size size of buffer
*
* @return number of bytes read/written, 0 on end of stream, negative on error
*/
typedef int32_t (*CompressIoCallback)(void* context, uint8_t* buffer, size_t size);
/** Decompress streamed data
*
* @param compress Compress instance
* @param read_cb read callback
* @param read_context read callback context
* @param write_cb write callback
* @param write_context write callback context
*
* @note Does not expect a header, just compressed data stream.
* @return true on success
*/
bool compress_decode_streamed(
Compress* compress,
CompressIoCallback read_cb,
void* read_context,
CompressIoCallback write_cb,
void* write_context);
//////////////////////////////////////////////////////////////////////////
/** CompressStreamDecoder control structure */
typedef struct CompressStreamDecoder CompressStreamDecoder;
/** Allocate stream decoder
*
* @param type Compression type
* @param[in] config Configuration for compression, specific to type
* @param read_cb The read callback for input (compressed) data
* @param read_context The read context
*
* @return CompressStreamDecoder instance
*/
CompressStreamDecoder* compress_stream_decoder_alloc(
CompressType type,
const void* config,
CompressIoCallback read_cb,
void* read_context);
/** Free stream decoder
*
* @param instance The CompressStreamDecoder instance
*/
void compress_stream_decoder_free(CompressStreamDecoder* instance);
/** Read uncompressed data chunk from stream decoder
*
* @param instance The CompressStreamDecoder instance
* @param data_out The data out
* @param[in] data_out_size The data out size
*
* @return true on success
*/
bool compress_stream_decoder_read(
CompressStreamDecoder* instance,
uint8_t* data_out,
size_t data_out_size);
/** Seek to position in uncompressed data stream
*
* @param instance The CompressStreamDecoder instance
* @param[in] position The position
*
* @return true on success
* @warning Backward seeking is not supported
*/
bool compress_stream_decoder_seek(CompressStreamDecoder* instance, size_t position);
/** Get current position in uncompressed data stream
*
* @param instance The CompressStreamDecoder instance
*
* @return current position
*/
size_t compress_stream_decoder_tell(CompressStreamDecoder* instance);
/** Reset stream decoder to the beginning
* @warning Read callback must be repositioned by caller separately
*
* @param instance The CompressStreamDecoder instance
*
* @return true on success
*/
bool compress_stream_decoder_rewind(CompressStreamDecoder* instance);
#ifdef __cplusplus
}
#endif