mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-13 05:06:30 +04:00
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>
This commit is contained in:
@@ -44,17 +44,34 @@ void compress_icon_free(CompressIcon* instance);
|
||||
*/
|
||||
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 compress_buff_size size of decoder and encoder buffer to
|
||||
* allocate
|
||||
* @param type Compression type
|
||||
* @param[in] config Configuration for compression, specific to type
|
||||
*
|
||||
* @return Compress instance
|
||||
*/
|
||||
Compress* compress_alloc(uint16_t compress_buff_size);
|
||||
Compress* compress_alloc(CompressType type, const void* config);
|
||||
|
||||
/** Free encoder and decoder
|
||||
*
|
||||
@@ -71,6 +88,8 @@ void compress_free(Compress* compress);
|
||||
* @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(
|
||||
@@ -90,6 +109,7 @@ bool compress_encode(
|
||||
* @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(
|
||||
@@ -100,6 +120,100 @@ bool compress_decode(
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user