diff --git a/scripts/LVGLImage.py b/scripts/LVGLImage.py index 56e3b0ca0..694e15f85 100755 --- a/scripts/LVGLImage.py +++ b/scripts/LVGLImage.py @@ -14,6 +14,12 @@ except ImportError: raise ImportError("Need pypng package, do `pip3 install pypng`") +try: + import lz4.block +except ImportError: + raise ImportError("Need lz4 package, do `pip3 install lz4`") + + def uint8_t(val) -> bytes: return val.to_bytes(1, byteorder='little') @@ -94,6 +100,7 @@ class PngQuant: class CompressMethod(Enum): NONE = 0x00 RLE = 0x01 + LZ4 = 0x02 class ColorFormat(Enum): @@ -365,6 +372,8 @@ class LVGLCompressData: pad = b'\x00' * (self.blk_size - self.raw_data_len % self.blk_size) self.raw_data_len += len(pad) compressed = RLEImage().rle_compress(raw_data + pad, self.blk_size) + elif self.compress == CompressMethod.LZ4: + compressed = lz4.block.compress(raw_data, store_size=False) else: raise ParameterError(f"Invalid compress method: {self.compress}") @@ -1069,7 +1078,7 @@ def main(): parser.add_argument('--compress', help=("Binary data compress method, default to NONE"), default="NONE", - choices=["NONE", "RLE"]) + choices=["NONE", "RLE", "LZ4"]) parser.add_argument('--align', help="stride alignment in bytes for bin image", diff --git a/src/libs/bin_decoder/lv_bin_decoder.c b/src/libs/bin_decoder/lv_bin_decoder.c index 040adf060..90dc7c98f 100644 --- a/src/libs/bin_decoder/lv_bin_decoder.c +++ b/src/libs/bin_decoder/lv_bin_decoder.c @@ -12,6 +12,7 @@ #include "../../stdlib/lv_string.h" #include "../../stdlib/lv_sprintf.h" #include "../../libs/rle/lv_rle.h" +#include "../../libs/lz4/lz4.h" /********************* * DEFINES @@ -846,6 +847,23 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image return LV_RESULT_INVALID; #endif } + else if(compressed->method == LV_IMAGE_COMPRESS_LZ4) { +#if LV_USE_LZ4 + const char * input = (const char *)compressed->data; + char * output = (char *)decompressed; + int len; + len = LZ4_decompress_safe(input, output, input_len, out_len); + if(len < 0 || (uint32_t)len != compressed->decompressed_size) { + LV_LOG_WARN("Decompress failed: %" LV_PRId32 ", got: %" LV_PRId32, out_len, len); + lv_draw_buf_free(decompressed); + return LV_RESULT_INVALID; + } +#else + LV_LOG_WARN("LZ4 decompress is not enabled"); + lv_draw_buf_free(decompressed); + return LV_RESULT_INVALID; +#endif + } decoder_data->decompressed = decompressed; /*Free on decoder close*/ return LV_RESULT_OK; diff --git a/tests/ref_imgs/draw/image_format_lz4_compressed.png b/tests/ref_imgs/draw/image_format_lz4_compressed.png new file mode 100644 index 000000000..2b23ce469 Binary files /dev/null and b/tests/ref_imgs/draw/image_format_lz4_compressed.png differ diff --git a/tests/ref_imgs/draw/image_format_lz4_compressed_rotate.png b/tests/ref_imgs/draw/image_format_lz4_compressed_rotate.png new file mode 100644 index 000000000..3f5264cab Binary files /dev/null and b/tests/ref_imgs/draw/image_format_lz4_compressed_rotate.png differ diff --git a/tests/ref_imgs/draw/image_format_lz4_compressed_rotate_recolor.png b/tests/ref_imgs/draw/image_format_lz4_compressed_rotate_recolor.png new file mode 100644 index 000000000..4a316b337 Binary files /dev/null and b/tests/ref_imgs/draw/image_format_lz4_compressed_rotate_recolor.png differ diff --git a/tests/src/lv_test_conf_full.h b/tests/src/lv_test_conf_full.h index 624b9735d..b7db43973 100644 --- a/tests/src/lv_test_conf_full.h +++ b/tests/src/lv_test_conf_full.h @@ -77,6 +77,7 @@ #define LV_USE_SYSMON 1 #define LV_USE_SNAPSHOT 1 #define LV_USE_THORVG_INTERNAL 1 +#define LV_USE_LZ4 1 #define LV_USE_LZ4_INTERNAL 1 #define LV_USE_VECTOR_GRAPHIC 1 diff --git a/tests/src/test_cases/draw/test_image_formats.c b/tests/src/test_cases/draw/test_image_formats.c index 4489e4a80..2980852b1 100644 --- a/tests/src/test_cases/draw/test_image_formats.c +++ b/tests/src/test_cases/draw/test_image_formats.c @@ -283,4 +283,67 @@ void test_image_rle_compressed_decode_rotate_recolor(void) #endif } +void test_image_lz4_compressed_decode(void) +{ +#if LV_USE_LZ4 + img_create("lz4A1", "A:src/test_files/lz4_compressed/cogwheel.A1.bin", false, false); + img_create("lz4A2", "A:src/test_files/lz4_compressed/cogwheel.A2.bin", false, false); + img_create("lz4A4", "A:src/test_files/lz4_compressed/cogwheel.A4.bin", false, false); + img_create("lz4A8", "A:src/test_files/lz4_compressed/cogwheel.A8.bin", false, false); + img_create("lz4I1", "A:src/test_files/lz4_compressed/cogwheel.I1.bin", false, false); + img_create("lz4I2", "A:src/test_files/lz4_compressed/cogwheel.I2.bin", false, false); + img_create("lz4I4", "A:src/test_files/lz4_compressed/cogwheel.I4.bin", false, false); + img_create("lz4I8", "A:src/test_files/lz4_compressed/cogwheel.I8.bin", false, false); + img_create("lz4RGB565A8", "A:src/test_files/lz4_compressed/cogwheel.RGB565A8.bin", false, false); + img_create("lz4RGB565", "A:src/test_files/lz4_compressed/cogwheel.RGB565.bin", false, false); + img_create("lz4RGB888", "A:src/test_files/lz4_compressed/cogwheel.RGB888.bin", false, false); + img_create("lz4XRGB8888", "A:src/test_files/lz4_compressed/cogwheel.XRGB8888.bin", false, false); + img_create("lz4ARGB8888", "A:src/test_files/lz4_compressed/cogwheel.ARGB8888.bin", false, false); + + TEST_ASSERT_EQUAL_SCREENSHOT("draw/image_format_lz4_compressed.png"); +#endif +} + +void test_image_lz4_compressed_decode_rotate(void) +{ +#if LV_USE_LZ4 + img_create("lz4A1", "A:src/test_files/lz4_compressed/cogwheel.A1.bin", true, false); + img_create("lz4A2", "A:src/test_files/lz4_compressed/cogwheel.A2.bin", true, false); + img_create("lz4A4", "A:src/test_files/lz4_compressed/cogwheel.A4.bin", true, false); + img_create("lz4A8", "A:src/test_files/lz4_compressed/cogwheel.A8.bin", true, false); + img_create("lz4I1", "A:src/test_files/lz4_compressed/cogwheel.I1.bin", true, false); + img_create("lz4I2", "A:src/test_files/lz4_compressed/cogwheel.I2.bin", true, false); + img_create("lz4I4", "A:src/test_files/lz4_compressed/cogwheel.I4.bin", true, false); + img_create("lz4I8", "A:src/test_files/lz4_compressed/cogwheel.I8.bin", true, false); + img_create("lz4RGB565A8", "A:src/test_files/lz4_compressed/cogwheel.RGB565A8.bin", true, false); + img_create("lz4RGB565", "A:src/test_files/lz4_compressed/cogwheel.RGB565.bin", true, false); + img_create("lz4RGB888", "A:src/test_files/lz4_compressed/cogwheel.RGB888.bin", true, false); + img_create("lz4XRGB8888", "A:src/test_files/lz4_compressed/cogwheel.XRGB8888.bin", true, false); + img_create("lz4ARGB8888", "A:src/test_files/lz4_compressed/cogwheel.ARGB8888.bin", true, false); + + TEST_ASSERT_EQUAL_SCREENSHOT("draw/image_format_lz4_compressed_rotate.png"); +#endif +} + +void test_image_lz4_compressed_decode_rotate_recolor(void) +{ +#if LV_USE_LZ4 + img_create("lz4A1", "A:src/test_files/lz4_compressed/cogwheel.A1.bin", true, true); + img_create("lz4A2", "A:src/test_files/lz4_compressed/cogwheel.A2.bin", true, true); + img_create("lz4A4", "A:src/test_files/lz4_compressed/cogwheel.A4.bin", true, true); + img_create("lz4A8", "A:src/test_files/lz4_compressed/cogwheel.A8.bin", true, true); + img_create("lz4I1", "A:src/test_files/lz4_compressed/cogwheel.I1.bin", true, true); + img_create("lz4I2", "A:src/test_files/lz4_compressed/cogwheel.I2.bin", true, true); + img_create("lz4I4", "A:src/test_files/lz4_compressed/cogwheel.I4.bin", true, true); + img_create("lz4I8", "A:src/test_files/lz4_compressed/cogwheel.I8.bin", true, true); + img_create("lz4RGB565A8", "A:src/test_files/lz4_compressed/cogwheel.RGB565A8.bin", true, true); + img_create("lz4RGB565", "A:src/test_files/lz4_compressed/cogwheel.RGB565.bin", true, true); + img_create("lz4RGB888", "A:src/test_files/lz4_compressed/cogwheel.RGB888.bin", true, true); + img_create("lz4XRGB8888", "A:src/test_files/lz4_compressed/cogwheel.XRGB8888.bin", true, true); + img_create("lz4ARGB8888", "A:src/test_files/lz4_compressed/cogwheel.ARGB8888.bin", true, true); + + TEST_ASSERT_EQUAL_SCREENSHOT("draw/image_format_lz4_compressed_rotate_recolor.png"); +#endif +} + #endif diff --git a/tests/src/test_files/lz4_compressed/cogwheel.A1.bin b/tests/src/test_files/lz4_compressed/cogwheel.A1.bin new file mode 100644 index 000000000..b14cf87b8 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.A1.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.A2.bin b/tests/src/test_files/lz4_compressed/cogwheel.A2.bin new file mode 100644 index 000000000..a4b8e8876 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.A2.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.A4.bin b/tests/src/test_files/lz4_compressed/cogwheel.A4.bin new file mode 100644 index 000000000..50cdd1396 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.A4.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.A8.bin b/tests/src/test_files/lz4_compressed/cogwheel.A8.bin new file mode 100644 index 000000000..e032c0124 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.A8.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.ARGB8888.bin b/tests/src/test_files/lz4_compressed/cogwheel.ARGB8888.bin new file mode 100644 index 000000000..0ca48deab Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.ARGB8888.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.I1.bin b/tests/src/test_files/lz4_compressed/cogwheel.I1.bin new file mode 100644 index 000000000..29b40cb3d Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.I1.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.I2.bin b/tests/src/test_files/lz4_compressed/cogwheel.I2.bin new file mode 100644 index 000000000..84d1403c0 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.I2.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.I4.bin b/tests/src/test_files/lz4_compressed/cogwheel.I4.bin new file mode 100644 index 000000000..b199fff90 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.I4.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.I8.bin b/tests/src/test_files/lz4_compressed/cogwheel.I8.bin new file mode 100644 index 000000000..6c1d62c8e Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.I8.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.RGB565.bin b/tests/src/test_files/lz4_compressed/cogwheel.RGB565.bin new file mode 100644 index 000000000..1787d498a Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.RGB565.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.RGB565A8.bin b/tests/src/test_files/lz4_compressed/cogwheel.RGB565A8.bin new file mode 100644 index 000000000..4b21c9d57 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.RGB565A8.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.RGB888.bin b/tests/src/test_files/lz4_compressed/cogwheel.RGB888.bin new file mode 100644 index 000000000..20c2ceb44 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.RGB888.bin differ diff --git a/tests/src/test_files/lz4_compressed/cogwheel.XRGB8888.bin b/tests/src/test_files/lz4_compressed/cogwheel.XRGB8888.bin new file mode 100644 index 000000000..2d789f6b7 Binary files /dev/null and b/tests/src/test_files/lz4_compressed/cogwheel.XRGB8888.bin differ