From b12855ee6ac7e4b7c8ac63a02cd444d3363b12ac Mon Sep 17 00:00:00 2001 From: Jannis Achstetter Date: Fri, 11 Jun 2021 23:09:34 +0200 Subject: [PATCH] Add brotly as compression algorithm and make it optional, as well as zstd due to binary file size --- .gitmodules | 3 +++ lib/brotli | 1 + src/CMakeLists.txt | 20 ++++++++++++++++++++ src/algo-brotli.c | 18 ++++++++++++++++++ src/algo-brotli.h | 10 ++++++++++ src/main.c | 24 ++++++++++++++++++++---- 6 files changed, 72 insertions(+), 4 deletions(-) create mode 160000 lib/brotli create mode 100644 src/algo-brotli.c create mode 100644 src/algo-brotli.h diff --git a/.gitmodules b/.gitmodules index d04a4a3..270221b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "lib/zlib"] path = lib/zlib url = https://github.com/kripton/zlib.git +[submodule "lib/brotli"] + path = lib/brotli + url = https://github.com/kripton/brotli.git diff --git a/lib/brotli b/lib/brotli new file mode 160000 index 0000000..6ea61d7 --- /dev/null +++ b/lib/brotli @@ -0,0 +1 @@ +Subproject commit 6ea61d7445bb48db9ccc6838a93adf6a2d3532c2 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index deccb13..d2baae2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,11 +10,16 @@ project(rp2040-compressiontest) ## Init the pico-sdk. Will instruct the user what to do if deps are missing pico_sdk_init() +## Needed so we can fit all compression algos into the Picos flash +## See below. However, needs to be set here in order to be effective +add_compile_options(-Os) + ## Include the CMakeLists-files of (non-pico-sdk)-libraries we will be using include(../lib/heatshrink/CMakeLists.txt) include(../lib/zlib/interfaceLibForPicoSDK.cmake) include(../lib/zstd/interfaceLibForPicoSDK.cmake) include(../lib/snappy/interfaceLibForPicoSDK.cmake) +include(../lib/brotli/interfaceLibForPicoSDK.cmake) ## Add our own C/C++ files here ## Sorted alphabetically @@ -24,9 +29,23 @@ add_executable(${CMAKE_PROJECT_NAME} algo-zlib.c algo-zstd.c algo-snappy.c + algo-brotli.c main.c ) +## Unfortunately, including all algortihms would result in a binary file +## too large for the Pico board (~2.7MB vs. 2MB available) +## We could try -Os but that contradicts our benchmarking effort ... UPDATE: +## just trying it revealed that the code is not that much slower. +## Using -flto broke the build :/ +## This is why you can either exclude ZSTD OR BROTLI, which both add a +## remarkable amount to the size of the UF2 file. +## When using -Os (see above), all algos just fit +target_compile_definitions(${CMAKE_PROJECT_NAME} + PUBLIC HAVE_ALGO_ZSTD=1 + PUBLIC HAVE_ALGO_BROTLI=1 +) + ## Config for the heatshrink library target_compile_definitions(${CMAKE_PROJECT_NAME} PUBLIC HEATSHRINK_DYNAMIC_ALLOC=0 @@ -54,6 +73,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME} zlib zstd snappy + brotli ) ## enable usb output, disable uart output diff --git a/src/algo-brotli.c b/src/algo-brotli.c new file mode 100644 index 0000000..f7a16a4 --- /dev/null +++ b/src/algo-brotli.c @@ -0,0 +1,18 @@ +#include "algo-zlib.h" + +#include "../lib/brotli/c/include/brotli/encode.h" +#include "../lib/brotli/c/include/brotli/decode.h" + +void brotli_init() +{ +} + +void brotli_compress(uint8_t *input, size_t insize, uint8_t *output, size_t *outsize) +{ + BrotliEncoderCompress(1, 10, BROTLI_DEFAULT_MODE, insize, input, outsize, output); +} + +void brotli_uncompress(uint8_t *input, size_t insize, uint8_t *output, size_t *outsize) +{ + BrotliDecoderDecompress(insize, input, outsize, output); +} diff --git a/src/algo-brotli.h b/src/algo-brotli.h new file mode 100644 index 0000000..931084b --- /dev/null +++ b/src/algo-brotli.h @@ -0,0 +1,10 @@ +#ifndef __ALGO_BROTLI_H__ +#define __ALGO_BROTLI_H__ + +#include "pico/stdlib.h" + +void brotli_init(); +void brotli_compress(uint8_t* input, size_t insize, uint8_t* output, size_t* outsize); +void brotli_uncompress(uint8_t* input, size_t insize, uint8_t* output, size_t* outsize); + +#endif // __ALGO_BROTLI_H__ diff --git a/src/main.c b/src/main.c index 61821cd..475e43b 100644 --- a/src/main.c +++ b/src/main.c @@ -17,8 +17,13 @@ #include "algo-heatshrink.h" #include "algo-zlib.h" +#if HAVE_ALGO_ZSTD #include "algo-zstd.h" +#endif #include "algo-snappy.h" +#if HAVE_ALGO_BROTLI +#include "algo-brotli.h" +#endif // TEST VECTORS @@ -54,8 +59,13 @@ struct algo { enum { ALGO_HEATSHRINK, ALGO_ZLIB, +#if HAVE_ALGO_ZSTD ALGO_ZSTD, +#endif ALGO_SNAPPY, +#if HAVE_ALGO_BROTLI + ALGO_BROTLI, +#endif // Add more HERE ALGO_NUM_TOTAL }; @@ -179,34 +189,40 @@ int main() { printf("Initializing compression algorithms ... "); start_time = time_us_32(); - // Algo 0: heatshrink sprintf(algos[ALGO_HEATSHRINK].name, "HEATSHRINK"); algos[ALGO_HEATSHRINK].init = heatshrink_init; algos[ALGO_HEATSHRINK].compress = heatshrink_compress; algos[ALGO_HEATSHRINK].uncompress = heatshrink_uncompress; algos[ALGO_HEATSHRINK].init(); - // Algo 1: zlib sprintf(algos[ALGO_ZLIB].name, "ZLIB"); algos[ALGO_ZLIB].init = zlib_init; algos[ALGO_ZLIB].compress = zlib_compress; algos[ALGO_ZLIB].uncompress = zlib_uncompress; algos[ALGO_ZLIB].init(); - // Algo 2: zstd +#if HAVE_ALGO_ZSTD sprintf(algos[ALGO_ZSTD].name, "ZSTD"); algos[ALGO_ZSTD].init = zstd_init; algos[ALGO_ZSTD].compress = zstd_compress; algos[ALGO_ZSTD].uncompress = zstd_uncompress; algos[ALGO_ZSTD].init(); +#endif - // Algo 2: snappy sprintf(algos[ALGO_SNAPPY].name, "SNAPPY"); algos[ALGO_SNAPPY].init = mysnappy_init; algos[ALGO_SNAPPY].compress = mysnappy_compress; algos[ALGO_SNAPPY].uncompress = mysnappy_uncompress; algos[ALGO_SNAPPY].init(); +#if HAVE_ALGO_BROTLI + sprintf(algos[ALGO_BROTLI].name, "BROTLI"); + algos[ALGO_BROTLI].init = brotli_init; + algos[ALGO_BROTLI].compress = brotli_compress; + algos[ALGO_BROTLI].uncompress = brotli_uncompress; + algos[ALGO_BROTLI].init(); +#endif + finish_time = time_us_32(); elapsed_time = finish_time - start_time; printf("%luµs\n", elapsed_time);