1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(image): add LZ4 compressed binary image support (#4873)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu 2023-11-30 20:20:31 +08:00 committed by GitHub
parent 2dadaaebad
commit 0233247406
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 92 additions and 1 deletions

View File

@ -14,6 +14,12 @@ except ImportError:
raise ImportError("Need pypng package, do `pip3 install pypng`") 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: def uint8_t(val) -> bytes:
return val.to_bytes(1, byteorder='little') return val.to_bytes(1, byteorder='little')
@ -94,6 +100,7 @@ class PngQuant:
class CompressMethod(Enum): class CompressMethod(Enum):
NONE = 0x00 NONE = 0x00
RLE = 0x01 RLE = 0x01
LZ4 = 0x02
class ColorFormat(Enum): class ColorFormat(Enum):
@ -365,6 +372,8 @@ class LVGLCompressData:
pad = b'\x00' * (self.blk_size - self.raw_data_len % self.blk_size) pad = b'\x00' * (self.blk_size - self.raw_data_len % self.blk_size)
self.raw_data_len += len(pad) self.raw_data_len += len(pad)
compressed = RLEImage().rle_compress(raw_data + pad, self.blk_size) 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: else:
raise ParameterError(f"Invalid compress method: {self.compress}") raise ParameterError(f"Invalid compress method: {self.compress}")
@ -1069,7 +1078,7 @@ def main():
parser.add_argument('--compress', parser.add_argument('--compress',
help=("Binary data compress method, default to NONE"), help=("Binary data compress method, default to NONE"),
default="NONE", default="NONE",
choices=["NONE", "RLE"]) choices=["NONE", "RLE", "LZ4"])
parser.add_argument('--align', parser.add_argument('--align',
help="stride alignment in bytes for bin image", help="stride alignment in bytes for bin image",

View File

@ -12,6 +12,7 @@
#include "../../stdlib/lv_string.h" #include "../../stdlib/lv_string.h"
#include "../../stdlib/lv_sprintf.h" #include "../../stdlib/lv_sprintf.h"
#include "../../libs/rle/lv_rle.h" #include "../../libs/rle/lv_rle.h"
#include "../../libs/lz4/lz4.h"
/********************* /*********************
* DEFINES * DEFINES
@ -846,6 +847,23 @@ static lv_result_t decompress_image(lv_image_decoder_dsc_t * dsc, const lv_image
return LV_RESULT_INVALID; return LV_RESULT_INVALID;
#endif #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*/ decoder_data->decompressed = decompressed; /*Free on decoder close*/
return LV_RESULT_OK; return LV_RESULT_OK;

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -77,6 +77,7 @@
#define LV_USE_SYSMON 1 #define LV_USE_SYSMON 1
#define LV_USE_SNAPSHOT 1 #define LV_USE_SNAPSHOT 1
#define LV_USE_THORVG_INTERNAL 1 #define LV_USE_THORVG_INTERNAL 1
#define LV_USE_LZ4 1
#define LV_USE_LZ4_INTERNAL 1 #define LV_USE_LZ4_INTERNAL 1
#define LV_USE_VECTOR_GRAPHIC 1 #define LV_USE_VECTOR_GRAPHIC 1

View File

@ -283,4 +283,67 @@ void test_image_rle_compressed_decode_rotate_recolor(void)
#endif #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 #endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.