feat(color): Compress font data with LZ4 (#4366)

This commit is contained in:
philmoz
2023-12-09 13:04:29 +10:00
committed by GitHub
parent b4f5ed5720
commit ecd50cf5e0
45 changed files with 98766 additions and 273255 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+251
View File
@@ -0,0 +1,251 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
Tool to convert an LVGL font (in 'lvgl' format) to an LZ4 compressed format
that can be uncompressed and reconstituted at runtime.
The font to be compressed must be in the file 'lv_font.inc'.
Usage:
Create the lv_font.inc file using the lv_font_conv program
Compile this program with GCC
Run this program with the font name as the first argument
Designed to be used by the make_fonts.sh tool, not run standalone.
Overview:
The font to be compressed is read from the structures in the lv_font.inc file.
Including and compiling with this files saves the effort of writing a parser
for the 'lvgl' font data.
Data that can be compressed is collected into a byte array and then LZ4 compressed.
The remaining data, and offsets needed to rebuild the LVGL font structures are
collected into custom structures (see lz4_fonts.h).
Everything is then written back out to the argv[1].c file to be compiled into
the EdgeTx firmware.
Note:
This is dependant on the LVGL font structure formats. If the LVGL version is
changed re-check that the font structure are still compatible.
*/
#include <stdio.h>
#include <stdlib.h>
#include "../../lv_conf.h"
#define LV_CONF_SKIP 1
#include "lv_font.inc"
#include "lz4/lz4hc.h"
#include "../../gui/colorlcd/lz4_fonts.h"
// Need this to allow lvgl to compile.
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t* font,
lv_font_glyph_dsc_t* dsc_out,
uint32_t unicode_letter,
uint32_t unicode_letter_next)
{
return true;
}
// Need this to allow lvgl to compile.
const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t letter)
{
return nullptr;
}
int main(int argc, char* argv[])
{
int uncomp_size = 0;
int comp_size = 0;
// Pointers to base LVGL font strucures
const lv_font_t* font = &lv_font;
lv_font_fmt_txt_dsc_t* dsc = (lv_font_fmt_txt_dsc_t*)font->dsc;
// Calculate size of data to compress
uncomp_size = sizeof(glyph_bitmap) + sizeof(glyph_dsc);
if (dsc->kern_classes) {
uncomp_size += sizeof(kern_class_values) + sizeof(kern_left_class_mapping) + sizeof(kern_right_class_mapping);
}
for (int i = 0; i < dsc->cmap_num; i += 1) {
if (dsc->cmaps[i].unicode_list)
uncomp_size += dsc->cmaps[i].list_length * sizeof(uint16_t);
if (dsc->cmaps[i].glyph_id_ofs_list)
uncomp_size += dsc->cmaps[i].list_length * sizeof(uint8_t);
}
// Create custom strucutre to hold font data
etxLz4Font etx_font;
memset(&etx_font, 0, sizeof(etxLz4Font));
// Copy font propeties
etx_font.line_height = font->line_height;
etx_font.base_line = font->base_line;
etx_font.subpx = font->subpx;
etx_font.underline_position = font->underline_position;
etx_font.underline_thickness = font->underline_thickness;
etx_font.kern_scale = dsc->kern_scale;
etx_font.cmap_num = dsc->cmap_num;
etx_font.bpp = dsc->bpp;
etx_font.kern_classes = dsc->kern_classes;
etx_font.bitmap_format = dsc->bitmap_format;
if (dsc->kern_classes) {
etx_font.left_class_cnt = kern_classes.left_class_cnt;
etx_font.right_class_cnt = kern_classes.right_class_cnt;
}
// Create custom cmap structure array
etxFontCmap* etx_cmaps = nullptr;
if (dsc->cmap_num > 0) {
etx_cmaps = (etxFontCmap*)malloc(dsc->cmap_num * sizeof(etxFontCmap));
memset(etx_cmaps, 0, dsc->cmap_num * sizeof(etxFontCmap));
// Copy properties
for (int i = 0; i < dsc->cmap_num; i += 1) {
etx_cmaps[i].range_start = dsc->cmaps[i].range_start;
etx_cmaps[i].range_length = dsc->cmaps[i].range_length;
etx_cmaps[i].glyph_id_start = dsc->cmaps[i].glyph_id_start;
etx_cmaps[i].list_length = dsc->cmaps[i].list_length;
etx_cmaps[i].type = dsc->cmaps[i].type;
}
}
// Allocate data blob
uint8_t* data = (uint8_t*)malloc(uncomp_size);
// Pointer to next available space in data blob
uint8_t* next = data;
memset(data, 0, uncomp_size);
// Copy compressable data and save offsets to each section
// glyph_dsc is always first at offset 0 - no offset needed
memcpy(next, glyph_dsc, sizeof(glyph_dsc));
next += sizeof(glyph_dsc);
// Copy cmaps array
for (int i = 0; i < dsc->cmap_num; i += 1) {
if (dsc->cmaps[i].unicode_list) {
memcpy(next, dsc->cmaps[i].unicode_list, dsc->cmaps[i].list_length * sizeof(uint16_t));
etx_cmaps[i].unicode_list = next - data;
next += dsc->cmaps[i].list_length * sizeof(uint16_t);
}
if (dsc->cmaps[i].glyph_id_ofs_list) {
memcpy(next, dsc->cmaps[i].glyph_id_ofs_list, dsc->cmaps[i].list_length * sizeof(uint8_t));
etx_cmaps[i].glyph_id_ofs_list = next - data;
next += dsc->cmaps[i].list_length * sizeof(uint8_t);
}
}
// Copy glyph_bitmap
memcpy(next, glyph_bitmap, sizeof(glyph_bitmap));
etx_font.glyph_bitmap = next - data;
next += sizeof(glyph_bitmap);
// Copy kern_classes (optional)
if (dsc->kern_classes) {
memcpy(next, kern_class_values, sizeof(kern_class_values));
etx_font.class_pair_values = next - data;
next += sizeof(kern_class_values);
memcpy(next, kern_left_class_mapping, sizeof(kern_left_class_mapping));
etx_font.left_class_mapping = next - data;
next += sizeof(kern_left_class_mapping);
memcpy(next, kern_right_class_mapping, sizeof(kern_right_class_mapping));
etx_font.right_class_mapping = next - data;
next += sizeof(kern_right_class_mapping);
}
// Allocate array and LZ4 compress data
uint8_t* lz4_data = (uint8_t*)malloc(uncomp_size);
comp_size = LZ4_compress_HC((const char*)data, (char*)lz4_data, uncomp_size, uncomp_size, 12);
// Write data to file
int i;
char filename[100];
snprintf(filename, 100,"%s.c",argv[1]);
FILE* fp = fopen(filename,"w");
fprintf(fp, "#include \"lz4_fonts.h\"\n\n");
// Compressed data
fprintf(fp, "static const uint8_t lz4FontData[] ={\n");
for (i = 0; i < comp_size; i += 1) {
fprintf(fp,"0x%02x,",lz4_data[i]);
if ((i & 0x0F) == 0x0F)
fprintf(fp, "\n");
}
if ((i & 0x0F) != 0)
fprintf(fp, "\n");
fprintf(fp, "};\n\n");
// Cmaps
if (dsc->cmap_num > 0) {
fprintf(fp, "static const etxFontCmap cmaps[] = {\n");
for (int i = 0; i < dsc->cmap_num; i += 1) {
fprintf(fp,"{ .range_start = %d, .range_length = %d, .glyph_id_start = %d, .list_length = %d, .type = %d, .unicode_list = %d, .glyph_id_ofs_list = %d },\n",
etx_cmaps[i].range_start, etx_cmaps[i].range_length, etx_cmaps[i].glyph_id_start, etx_cmaps[i].list_length,
etx_cmaps[i].type, etx_cmaps[i].unicode_list, etx_cmaps[i].glyph_id_ofs_list
);
}
fprintf(fp, "};\n\n");
}
// Custom font structure
fprintf(fp,"const etxLz4Font %s = {\n", argv[1]);
fprintf(fp,".uncomp_size = %d,\n",uncomp_size);
fprintf(fp,".comp_size = %d,\n",comp_size);
fprintf(fp,".line_height = %d,\n",etx_font.line_height);
fprintf(fp,".base_line = %d,\n",etx_font.base_line);
fprintf(fp,".subpx = %d,\n",etx_font.subpx);
fprintf(fp,".underline_position = %d,\n",etx_font.underline_position);
fprintf(fp,".underline_thickness = %d,\n",etx_font.underline_thickness);
fprintf(fp,".kern_scale = %d,\n",etx_font.kern_scale);
fprintf(fp,".cmap_num = %d,\n",etx_font.cmap_num);
fprintf(fp,".bpp = %d,\n",etx_font.bpp);
fprintf(fp,".kern_classes = %d,\n",etx_font.kern_classes);
fprintf(fp,".bitmap_format = %d,\n",etx_font.bitmap_format);
fprintf(fp,".left_class_cnt = %d,\n",etx_font.left_class_cnt);
fprintf(fp,".right_class_cnt = %d,\n",etx_font.right_class_cnt);
fprintf(fp,".glyph_bitmap = %d,\n",etx_font.glyph_bitmap);
fprintf(fp,".class_pair_values = %d,\n",etx_font.class_pair_values);
fprintf(fp,".left_class_mapping = %d,\n",etx_font.left_class_mapping);
fprintf(fp,".right_class_mapping = %d,\n",etx_font.right_class_mapping);
fprintf(fp,".cmaps = cmaps,\n");
fprintf(fp,".compressed = lz4FontData,\n");
fprintf(fp, "};\n");
fclose(fp);
printf("%s %d %d %d%%\n",argv[1],uncomp_size,comp_size,(comp_size * 100) / uncomp_size);
}
+33 -5
View File
@@ -43,6 +43,29 @@ function make_font() {
--format lvgl -o lv_font_${name}_${size}.c --force-fast-kern-format ${arg}
}
function compress_font() {
local name=$1
gcc -I ../../thirdparty/libopenui/thirdparty lz4_font.cpp ../../thirdparty/libopenui/thirdparty/lz4/lz4hc.c ../../thirdparty/libopenui/thirdparty/lz4/lz4.c -o lz4_font
./lz4_font ${name}
}
function make_font_lz4() {
local name=$1
local ttf=$2
local size=$3
local chars=$4
local arg=$5
lv_font_conv --no-prefilter --bpp 4 --size ${size} \
--font ${TTF_DIR}${ttf} -r ${ASCII},${DEGREE},${BULLET},${COMPARE}${chars} \
--font EdgeTX/extra.ttf -r ${EXTRA_SYM} \
--font ${ARROWS_FONT} -r ${ARROWS} \
--font ${SYMBOLS_FONT} -r ${SYMBOLS} \
--format lvgl -o lv_font.inc --force-fast-kern-format ${arg}
compress_font lv_font_${name}_${size}
}
function make_font_w_extra_sym() {
local name=$1
local ttf=$2
@@ -53,7 +76,8 @@ function make_font_w_extra_sym() {
lv_font_conv --no-prefilter --bpp 4 --size ${size} \
--font ${TTF_DIR}${ttf} -r ${ASCII},${DEGREE}${chars} \
--font EdgeTX/extra.ttf -r ${EXTRA_SYM} \
--format lvgl -o lv_font_${name}_${size}.c --force-fast-kern-format ${arg}
--format lvgl -o lv_font.inc --force-fast-kern-format ${arg}
compress_font lv_font_${name}_${size}
}
function make_font_no_sym() {
@@ -65,7 +89,8 @@ function make_font_no_sym() {
lv_font_conv --no-prefilter --bpp 4 --size ${size} \
--font ${TTF_DIR}${ttf} -r ${ASCII},${DEGREE}${chars} \
--format lvgl -o lv_font_${name}_${size}.c --force-fast-kern-format ${arg}
--format lvgl -o lv_font.inc --force-fast-kern-format ${arg}
compress_font lv_font_${name}_${size}
}
# LV_SYMBOL_CHARGE, LV_SYMBOL_NEW_LINE, LV_SYMBOL_SD_CARD, LV_SYMBOL_CLOSE
@@ -88,10 +113,10 @@ function make_font_set() {
local ttf_bold=$3
local chars=$4
make_font "${name}" "${ttf_normal}" 9 ${chars} --no-compress
make_font "${name}" "${ttf_normal}" 13 ${chars} --no-compress
make_font_lz4 "${name}" "${ttf_normal}" 9 ${chars} --no-compress
make_font_lz4 "${name}" "${ttf_normal}" 13 ${chars} --no-compress
make_font "${name}" "${ttf_normal}" 16 ${chars} --no-compress
make_font "${name}_bold" "${ttf_bold}" 16 ${chars}
make_font_lz4 "${name}_bold" "${ttf_bold}" 16 ${chars}
make_font_w_extra_sym "${name}" "${ttf_normal}" 24 ${chars}
make_font_no_sym "${name}_bold" "${ttf_bold}" 32 ${chars}
make_font_no_sym "${name}_bold" "${ttf_bold}" 64
@@ -109,3 +134,6 @@ make_font_set "noto_cn" "Noto/NotoSansCJKsc-Regular.otf" "Noto/NotoSansCJKsc-Bol
make_font_set "noto_jp" "Noto/NotoSansCJKsc-Regular.otf" "Noto/NotoSansCJKsc-Bold.otf" ",${JP_SYMBOLS}"
make_font_set "arimo_he" "Arimo/Arimo-Regular.ttf" "Arimo/Arimo-Bold.ttf" ",${HE_SYMBOLS}"
make_font_set "arimo_ru" "Arimo/Arimo-Regular.ttf" "Arimo/Arimo-Bold.ttf" ",${RU_SYMBOLS}"
rm lv_font.inc
rm lz4_font
+165 -27
View File
@@ -19,47 +19,185 @@
* GNU General Public License for more details.
*/
#include "libopenui_defines.h"
#include <stdio.h>
#include <stdlib.h>
#include "font.h"
#include "libopenui/thirdparty/lz4/lz4.h"
#include "libopenui_defines.h"
#include "lz4_fonts.h"
#if !defined(BOOT)
#define FONT_TABLE(name) \
extern const etxLz4Font lv_font_##name##_bold_16; \
extern const etxLz4Font lv_font_##name##_9; \
extern const etxLz4Font lv_font_##name##_13; \
extern const etxLz4Font lv_font_##name##_24; \
extern const etxLz4Font lv_font_##name##_bold_32; \
extern const etxLz4Font lv_font_##name##_bold_64; \
static const etxLz4Font* lz4FontTable[FONTS_COUNT] = { \
nullptr, /* FONT_STD_INDEX */ \
&lv_font_##name##_bold_16, /* FONT_BOLD_INDEX */ \
&lv_font_##name##_9, /* FONT_XXS_INDEX */ \
&lv_font_##name##_13, /* FONT_XS_INDEX */ \
&lv_font_##name##_24, /* FONT_L_INDEX */ \
&lv_font_##name##_bold_32, /* FONT_XL_INDEX */ \
&lv_font_##name##_bold_64, /* FONT_XXL_INDEX */ \
}; \
static const lv_font_t* lvglFontTable[FONTS_COUNT] = { \
LV_FONT_DEFAULT, /* FONT_STD_INDEX */ \
&lv_font_ ## name ## _bold_16, /* FONT_BOLD_INDEX */ \
&lv_font_ ## name ## _9, /* FONT_XXS_INDEX */ \
&lv_font_ ## name ## _13, /* FONT_XS_INDEX */ \
&lv_font_ ## name ## _24, /* FONT_L_INDEX */ \
&lv_font_ ## name ## _bold_32, /* FONT_XL_INDEX */ \
&lv_font_ ## name ## _bold_64, /* FONT_XXL_INDEX */ \
LV_FONT_DEFAULT, /* FONT_STD_INDEX */ \
nullptr, /* FONT_BOLD_INDEX */ \
nullptr, /* FONT_XXS_INDEX */ \
nullptr, /* FONT_XS_INDEX */ \
nullptr, /* FONT_L_INDEX */ \
nullptr, /* FONT_XL_INDEX */ \
nullptr, /* FONT_XXL_INDEX */ \
}
#if defined(TRANSLATIONS_CN)
FONT_TABLE(noto_cn);
FONT_TABLE(noto_cn);
#elif defined(TRANSLATIONS_TW)
FONT_TABLE(noto_tw);
FONT_TABLE(noto_tw);
#elif defined(TRANSLATIONS_JP)
FONT_TABLE(noto_jp);
FONT_TABLE(noto_jp);
#elif defined(TRANSLATIONS_HE)
FONT_TABLE(arimo_he);
FONT_TABLE(arimo_he);
#elif defined(TRANSLATIONS_RU)
FONT_TABLE(arimo_ru);
FONT_TABLE(arimo_ru);
#else
FONT_TABLE(roboto);
FONT_TABLE(roboto);
#endif
#endif // BOOT
/*
Decompress an LZ4 font and build LVGL font structures.
*/
void decompressFont(int idx)
{
// Check if already decompressed
if (lvglFontTable[idx]) return;
// used to set the line height to the line heights used in Edgetx < 2.7 and OpenTX
static const int8_t FontHeightCorrection[FONTS_COUNT] {
-2, // STD
-2, // BOLD
-2, // XXS
-2, // XS
-3, // L
-5, // XL
-2, // XXL
const etxLz4Font* etxFont = lz4FontTable[idx];
// Calculate size of memory block to allocate for uncompressed data plus LVGL
// font structures.
int size = etxFont->uncomp_size + sizeof(lv_font_t) +
sizeof(lv_font_fmt_txt_dsc_t) +
sizeof(lv_font_fmt_txt_glyph_cache_t) +
etxFont->cmap_num * sizeof(lv_font_fmt_txt_cmap_t);
if (etxFont->kern_classes) size += sizeof(lv_font_fmt_txt_kern_classes_t);
uint8_t* data = (uint8_t*)malloc(size);
if (data) {
memset(data, 0, size);
// Pointer to next free area in data block
uint8_t* next = data;
// 'Create' lv_font_t structure
lv_font_t* lvglFont = (lv_font_t*)next;
next += sizeof(lv_font_t);
// 'Create' lv_font_fmt_txt_dsc_t structure
lv_font_fmt_txt_dsc_t* lvglFontDsc = (lv_font_fmt_txt_dsc_t*)next;
next += sizeof(lv_font_fmt_txt_dsc_t);
// 'Create' lv_font_fmt_txt_glyph_cache_t structure
lv_font_fmt_txt_glyph_cache_t* lvglCache =
(lv_font_fmt_txt_glyph_cache_t*)next;
next += sizeof(lv_font_fmt_txt_glyph_cache_t);
// 'Create' lv_font_fmt_txt_kern_classes_t structure (optional)
lv_font_fmt_txt_kern_classes_t* lvglKernClasses = nullptr;
if (etxFont->kern_classes) {
lvglKernClasses = (lv_font_fmt_txt_kern_classes_t*)next;
next += sizeof(lv_font_fmt_txt_kern_classes_t);
}
// 'Create' lv_font_fmt_txt_cmap_t structure array
lv_font_fmt_txt_cmap_t* lvglCmaps = (lv_font_fmt_txt_cmap_t*)next;
next += sizeof(lv_font_fmt_txt_cmap_t) * etxFont->cmap_num;
// Decompress the compressed data into the remaining space
// 'next' is now the start of the uncompressed data
LZ4_decompress_safe((const char*)etxFont->compressed, (char*)next,
etxFont->comp_size, etxFont->uncomp_size);
// Rebuild the lv_font_t structure
// Relocate pointers
lvglFont->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt;
lvglFont->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt;
lvglFont->dsc = lvglFontDsc;
// Fill in other properties
lvglFont->line_height = etxFont->line_height;
lvglFont->base_line = etxFont->base_line;
lvglFont->subpx = etxFont->subpx;
lvglFont->underline_position = etxFont->underline_position;
lvglFont->underline_thickness = etxFont->underline_thickness;
// Rebuild the lv_font_fmt_txt_dsc_t structure
// Relocate pointers
lvglFontDsc->glyph_bitmap = &next[etxFont->glyph_bitmap];
lvglFontDsc->glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t*)&next[0];
lvglFontDsc->cmaps = lvglCmaps;
lvglFontDsc->kern_dsc = lvglKernClasses;
lvglFontDsc->kern_classes = etxFont->kern_classes;
lvglFontDsc->bitmap_format = etxFont->bitmap_format;
lvglFontDsc->cache = lvglCache;
// Fill in other properties
lvglFontDsc->kern_scale = etxFont->kern_scale;
lvglFontDsc->cmap_num = etxFont->cmap_num;
lvglFontDsc->bpp = etxFont->bpp;
// Rebuild the lv_font_fmt_txt_kern_classes_t structure
if (etxFont->kern_classes) {
// Relocate pointers
lvglKernClasses->class_pair_values =
(int8_t*)&next[etxFont->class_pair_values];
lvglKernClasses->left_class_mapping = &next[etxFont->left_class_mapping];
lvglKernClasses->right_class_mapping =
&next[etxFont->right_class_mapping];
// Fill in other properties
lvglKernClasses->left_class_cnt = etxFont->left_class_cnt;
lvglKernClasses->right_class_cnt = etxFont->right_class_cnt;
}
// Rebuild the lv_font_t lv_font_fmt_txt_cmap_t structure array
for (int i = 0; i < etxFont->cmap_num; i += 1) {
// Relocate pointers
if (etxFont->cmaps[i].unicode_list)
lvglCmaps[i].unicode_list =
(uint16_t*)&next[etxFont->cmaps[i].unicode_list];
if (etxFont->cmaps[i].glyph_id_ofs_list)
lvglCmaps[i].glyph_id_ofs_list =
&next[etxFont->cmaps[i].glyph_id_ofs_list];
// Fill in other properties
lvglCmaps[i].range_start = etxFont->cmaps[i].range_start;
lvglCmaps[i].range_length = etxFont->cmaps[i].range_length;
lvglCmaps[i].glyph_id_start = etxFont->cmaps[i].glyph_id_start;
lvglCmaps[i].list_length = etxFont->cmaps[i].list_length;
lvglCmaps[i].type = etxFont->cmaps[i].type;
}
// Save LVGL font to lookup array
lvglFontTable[idx] = lvglFont;
} else {
TRACE("No memory to decompress font %d", idx);
lvglFontTable[idx] = lvglFontTable[0];
}
}
#endif // BOOT
// used to set the line height to the line heights used in Edgetx < 2.7 and
// OpenTX
static const int8_t FontHeightCorrection[FONTS_COUNT] = {
-2, // ST
-2, // BOLD
-2, // XXS
-2, // XS
-3, // L
-5, // XL
-2, // XXL
};
const lv_font_t* getFont(LcdFlags flags)
@@ -69,6 +207,7 @@ const lv_font_t* getFont(LcdFlags flags)
#else
auto fontIndex = FONT_INDEX(flags);
if (fontIndex >= FONTS_COUNT) return LV_FONT_DEFAULT;
decompressFont(fontIndex);
return lvglFontTable[fontIndex];
#endif
}
@@ -81,11 +220,10 @@ uint8_t getFontHeight(LcdFlags flags)
uint8_t getFontHeightCondensed(LcdFlags flags)
{
auto font = getFont(flags);
return lv_font_get_line_height(font) + FontHeightCorrection[FONT_INDEX(flags)];
return getFontHeight(flags) + FontHeightCorrection[FONT_INDEX(flags)];
}
int getTextWidth(const char * s, int len, LcdFlags flags)
int getTextWidth(const char* s, int len, LcdFlags flags)
{
auto font = getFont(flags);
lv_coord_t letter_space = 0;
+80
View File
@@ -0,0 +1,80 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include <stdint.h>
/*
Structures for handling LZ4 compressed versions of LVGL fonts
Compressed data is uncompressed at runtime and these strucutres
then used to rebuild the LVGL font structures.
Note: this is dependant on the LVGL font structure formats. If
the LVGL version changes, re-check the LVGL font structures.
*/
typedef struct {
// Properties used to reconstitute the LVGL 'cmaps' array
uint16_t range_start; // lv_font_fmt_txt_cmap_t.range_start
uint16_t range_length; // lv_font_fmt_txt_cmap_t.range_length
uint16_t glyph_id_start; // lv_font_fmt_txt_cmap_t.glyph_id_start
uint16_t list_length; // lv_font_fmt_txt_cmap_t.list_length
uint16_t type; // lv_font_fmt_txt_cmap_t.type
// Offsets into uncompressed data to relocate pointers at runtime
uint32_t unicode_list; // lv_font_fmt_txt_cmap_t.unicode_list
uint32_t glyph_id_ofs_list; // lv_font_fmt_txt_cmap_t.glyph_id_ofs_list
} etxFontCmap;
typedef struct {
uint32_t uncomp_size; // Uncompressed data size
uint32_t comp_size; // Compressed data size
// Properties used to reconstitute the various LVGL font structures
uint8_t line_height; // lv_font_t.line_height
uint8_t base_line; // lv_font_t.base_line
uint8_t subpx; // lv_font_t.subpx
int8_t underline_position; // lv_font_t.underline_position
int8_t underline_thickness; // lv_font_t.underline_thickness
uint8_t kern_scale; // lv_font_fmt_txt_dsc_t.kern_scale
uint8_t cmap_num; // lv_font_fmt_txt_dsc_t.cmap_num
uint8_t bpp; // lv_font_fmt_txt_dsc_t.bpp
uint8_t kern_classes; // lv_font_fmt_txt_dsc_t.kern_classes
uint8_t bitmap_format; // lv_font_fmt_txt_dsc_t.bitmap_format
uint8_t left_class_cnt; // lv_font_fmt_txt_kern_classes_t.left_class_cnt
uint8_t right_class_cnt; // lv_font_fmt_txt_kern_classes_t.right_class_cnt
// Offsets into uncompressed data to relocate pointers at runtime
// Note: lv_font_fmt_txt_dsc_t.glyph_dsc is always at the start of the uncompressed data
uint32_t glyph_bitmap; // lv_font_fmt_txt_dsc_t.glyph_bitmap
uint32_t class_pair_values; // lv_font_fmt_txt_kern_classes_t.class_pair_values
uint32_t left_class_mapping; // lv_font_fmt_txt_kern_classes_t.left_class_mapping
uint32_t right_class_mapping; // lv_font_fmt_txt_kern_classes_t.right_class_mapping
// Pointers to cmaps and compressed data
const etxFontCmap* cmaps;
const uint8_t* compressed;
} etxLz4Font;
+6 -43
View File
@@ -394,78 +394,41 @@
#if defined(TRANSLATIONS_CN)
#define LV_FONT_CUSTOM_DECLARE \
LV_FONT_DECLARE(lv_font_noto_cn_9) \
LV_FONT_DECLARE(lv_font_noto_cn_13) \
LV_FONT_DECLARE(lv_font_noto_cn_16) \
LV_FONT_DECLARE(lv_font_noto_cn_24) \
LV_FONT_DECLARE(lv_font_noto_cn_bold_16) \
LV_FONT_DECLARE(lv_font_noto_cn_bold_32) \
LV_FONT_DECLARE(lv_font_noto_cn_bold_64)
LV_FONT_DECLARE(lv_font_noto_cn_16)
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_noto_cn_16
#elif defined(TRANSLATIONS_TW)
#define LV_FONT_CUSTOM_DECLARE \
LV_FONT_DECLARE(lv_font_noto_tw_9) \
LV_FONT_DECLARE(lv_font_noto_tw_13) \
LV_FONT_DECLARE(lv_font_noto_tw_16) \
LV_FONT_DECLARE(lv_font_noto_tw_24) \
LV_FONT_DECLARE(lv_font_noto_tw_bold_16) \
LV_FONT_DECLARE(lv_font_noto_tw_bold_32) \
LV_FONT_DECLARE(lv_font_noto_tw_bold_64)
LV_FONT_DECLARE(lv_font_noto_tw_16)
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_noto_tw_16
#elif defined(TRANSLATIONS_RU)
#define LV_FONT_CUSTOM_DECLARE \
LV_FONT_DECLARE(lv_font_arimo_ru_9) \
LV_FONT_DECLARE(lv_font_arimo_ru_13) \
LV_FONT_DECLARE(lv_font_arimo_ru_16) \
LV_FONT_DECLARE(lv_font_arimo_ru_24) \
LV_FONT_DECLARE(lv_font_arimo_ru_bold_16) \
LV_FONT_DECLARE(lv_font_arimo_ru_bold_32) \
LV_FONT_DECLARE(lv_font_arimo_ru_bold_64)
LV_FONT_DECLARE(lv_font_arimo_ru_16)
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_arimo_ru_16
#elif defined(TRANSLATIONS_JP)
#define LV_FONT_CUSTOM_DECLARE \
LV_FONT_DECLARE(lv_font_noto_jp_9) \
LV_FONT_DECLARE(lv_font_noto_jp_13) \
LV_FONT_DECLARE(lv_font_noto_jp_16) \
LV_FONT_DECLARE(lv_font_noto_jp_24) \
LV_FONT_DECLARE(lv_font_noto_jp_bold_16) \
LV_FONT_DECLARE(lv_font_noto_jp_bold_32) \
LV_FONT_DECLARE(lv_font_noto_jp_bold_64)
LV_FONT_DECLARE(lv_font_noto_jp_16)
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_noto_jp_16
#elif defined(TRANSLATIONS_HE)
#define LV_FONT_CUSTOM_DECLARE \
LV_FONT_DECLARE(lv_font_arimo_he_9) \
LV_FONT_DECLARE(lv_font_arimo_he_13) \
LV_FONT_DECLARE(lv_font_arimo_he_16) \
LV_FONT_DECLARE(lv_font_arimo_he_24) \
LV_FONT_DECLARE(lv_font_arimo_he_bold_16) \
LV_FONT_DECLARE(lv_font_arimo_he_bold_32) \
LV_FONT_DECLARE(lv_font_arimo_he_bold_64)
LV_FONT_DECLARE(lv_font_arimo_he_16)
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_arimo_he_16
#else
#define LV_FONT_CUSTOM_DECLARE \
LV_FONT_DECLARE(lv_font_roboto_9) \
LV_FONT_DECLARE(lv_font_roboto_13) \
LV_FONT_DECLARE(lv_font_roboto_16) \
LV_FONT_DECLARE(lv_font_roboto_24) \
LV_FONT_DECLARE(lv_font_roboto_bold_16) \
LV_FONT_DECLARE(lv_font_roboto_bold_32) \
LV_FONT_DECLARE(lv_font_roboto_bold_64)
LV_FONT_DECLARE(lv_font_roboto_16)
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_roboto_16
File diff suppressed because it is too large Load Diff
+146 -58
View File
@@ -1,7 +1,7 @@
/*
* LZ4 - Fast LZ compression algorithm
* Header File
* Copyright (C) 2011-present, Yann Collet.
* Copyright (C) 2011-2020, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
@@ -97,36 +97,77 @@ extern "C" {
# define LZ4LIB_API LZ4LIB_VISIBILITY
#endif
/*! LZ4_FREESTANDING :
* When this macro is set to 1, it enables "freestanding mode" that is
* suitable for typical freestanding environment which doesn't support
* standard C library.
*
* - LZ4_FREESTANDING is a compile-time switch.
* - It requires the following macros to be defined:
* LZ4_memcpy, LZ4_memmove, LZ4_memset.
* - It only enables LZ4/HC functions which don't use heap.
* All LZ4F_* functions are not supported.
* - See tests/freestanding.c to check its basic setup.
*/
#if defined(LZ4_FREESTANDING) && (LZ4_FREESTANDING == 1)
# define LZ4_HEAPMODE 0
# define LZ4HC_HEAPMODE 0
# define LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION 1
# if !defined(LZ4_memcpy)
# error "LZ4_FREESTANDING requires macro 'LZ4_memcpy'."
# endif
# if !defined(LZ4_memset)
# error "LZ4_FREESTANDING requires macro 'LZ4_memset'."
# endif
# if !defined(LZ4_memmove)
# error "LZ4_FREESTANDING requires macro 'LZ4_memmove'."
# endif
#elif ! defined(LZ4_FREESTANDING)
# define LZ4_FREESTANDING 0
#endif
/*------ Version ------*/
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */
#define LZ4_VERSION_RELEASE 3 /* for tweaks, bug-fixes, or development */
#define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
#define LZ4_QUOTE(str) #str
#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) /* requires v1.7.3+ */
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version */
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version; requires v1.3.0+ */
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version; requires v1.7.5+ */
/*-************************************
* Tuning parameter
**************************************/
#define LZ4_MEMORY_USAGE_MIN 10
#define LZ4_MEMORY_USAGE_DEFAULT 14
#define LZ4_MEMORY_USAGE_MAX 20
/*!
* LZ4_MEMORY_USAGE :
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
* Increasing memory usage improves compression ratio.
* Reduced memory usage may improve speed, thanks to better cache locality.
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; )
* Increasing memory usage improves compression ratio, at the cost of speed.
* Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality.
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
*/
#ifndef LZ4_MEMORY_USAGE
# define LZ4_MEMORY_USAGE 14
# define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT
#endif
#if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN)
# error "LZ4_MEMORY_USAGE is too small !"
#endif
#if (LZ4_MEMORY_USAGE > LZ4_MEMORY_USAGE_MAX)
# error "LZ4_MEMORY_USAGE is too large !"
#endif
/*-************************************
* Simple Functions
@@ -148,8 +189,9 @@ LZ4LIB_API const char* LZ4_versionString (void); /**< library version string;
LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
/*! LZ4_decompress_safe() :
* compressedSize : is the exact complete size of the compressed block.
* dstCapacity : is the size of destination buffer (which must be already allocated), presumed an upper bound of decompressed size.
* @compressedSize : is the exact complete size of the compressed block.
* @dstCapacity : is the size of destination buffer (which must be already allocated),
* is an upper bound of decompressed size.
* @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
* If destination buffer is not large enough, decoding will stop and output an error code (negative value).
* If the source stream is detected malformed, the function will stop decoding and return a negative result.
@@ -214,7 +256,7 @@ LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* d
* @return : Nb bytes written into 'dst' (necessarily <= targetDestSize)
* or 0 if compression fails.
*
* Note : from v1.8.2 to v1.9.1, this function had a bug (fixed un v1.9.2+):
* Note : from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+):
* the produced compressed content could, in specific circumstances,
* require to be decompressed into a destination buffer larger
* by at least 1 byte than the content to decompress.
@@ -270,8 +312,25 @@ LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcS
***********************************************/
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
/**
Note about RC_INVOKED
- RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio).
https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros
- Since rc.exe is a legacy compiler, it truncates long symbol (> 30 chars)
and reports warning "RC4011: identifier truncated".
- To eliminate the warning, we surround long preprocessor symbol with
"#if !defined(RC_INVOKED) ... #endif" block that means
"skip this block when rc.exe is trying to read it".
*/
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
#endif
/*! LZ4_resetStream_fast() : v1.9.0+
* Use this to prepare an LZ4_stream_t for a new chain of dependent blocks
@@ -355,8 +414,12 @@ typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */
* creation / destruction of streaming decompression tracking context.
* A tracking context can be re-used multiple times.
*/
#if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
#endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */
#endif
/*! LZ4_setStreamDecode() :
* An LZ4_streamDecode_t context can be allocated once and re-used multiple times.
@@ -381,11 +444,24 @@ LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const
LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
#define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */
/*! LZ4_decompress_*_continue() :
* These decoding functions allow decompression of consecutive blocks in "streaming" mode.
* A block is an unsplittable entity, it must be presented entirely to a decompression function.
* Decompression functions only accepts one block at a time.
* The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded.
/*! LZ4_decompress_safe_continue() :
* This decoding function allows decompression of consecutive blocks in "streaming" mode.
* The difference with the usual independent blocks is that
* new blocks are allowed to find references into former blocks.
* A block is an unsplittable entity, and must be presented entirely to the decompression function.
* LZ4_decompress_safe_continue() only accepts one block at a time.
* It's modeled after `LZ4_decompress_safe()` and behaves similarly.
*
* @LZ4_streamDecode : decompression state, tracking the position in memory of past data
* @compressedSize : exact complete size of one compressed block.
* @dstCapacity : size of destination buffer (which must be already allocated),
* must be an upper bound of decompressed size.
* @return : number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
* If destination buffer is not large enough, decoding will stop and output an error code (negative value).
* If the source stream is detected malformed, the function will stop decoding and return a negative result.
*
* The last 64KB of previously decoded data *must* remain available and unmodified
* at the memory position where they were previously decoded.
* If less than 64KB of data has been decoded, all the data must be present.
*
* Special : if decompression side sets a ring buffer, it must respect one of the following conditions :
@@ -406,18 +482,36 @@ LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize);
* save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression,
* then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block.
*/
LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity);
LZ4LIB_API int
LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode,
const char* src, char* dst,
int srcSize, int dstCapacity);
/*! LZ4_decompress_*_usingDict() :
* These decoding functions work the same as
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue()
* They are stand-alone, and don't need an LZ4_streamDecode_t structure.
/*! LZ4_decompress_safe_usingDict() :
* Works the same as
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_safe_continue()
* However, it's stateless: it doesn't need any LZ4_streamDecode_t state.
* Dictionary is presumed stable : it must remain accessible and unmodified during decompression.
* Performance tip : Decompression speed can be substantially increased
* when dst == dictStart + dictSize.
*/
LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize);
LZ4LIB_API int
LZ4_decompress_safe_usingDict(const char* src, char* dst,
int srcSize, int dstCapacity,
const char* dictStart, int dictSize);
/*! LZ4_decompress_safe_partial_usingDict() :
* Behaves the same as LZ4_decompress_safe_partial()
* with the added ability to specify a memory segment for past data.
* Performance tip : Decompression speed can be substantially increased
* when dst == dictStart + dictSize.
*/
LZ4LIB_API int
LZ4_decompress_safe_partial_usingDict(const char* src, char* dst,
int compressedSize,
int targetOutputSize, int maxOutputSize,
const char* dictStart, int dictSize);
#endif /* LZ4_H_2983827168210 */
@@ -496,13 +590,15 @@ LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const c
* stream (and source buffer) must remain in-place / accessible / unchanged
* through the completion of the first compression call on the stream.
*/
LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream);
LZ4LIB_STATIC_API void
LZ4_attach_dictionary(LZ4_stream_t* workingStream,
const LZ4_stream_t* dictionaryStream);
/*! In-place compression and decompression
*
* It's possible to have input and output sharing the same buffer,
* for highly contrained memory environments.
* for highly constrained memory environments.
* In both cases, it requires input to lay at the end of the buffer,
* and decompression to start at beginning of the buffer.
* Buffer size must feature some margin, hence be larger than final size.
@@ -592,38 +688,26 @@ LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const
typedef unsigned int LZ4_u32;
#endif
/*! LZ4_stream_t :
* Never ever use below internal definitions directly !
* These definitions are not API/ABI safe, and may change in future versions.
* If you need static allocation, declare or allocate an LZ4_stream_t object.
**/
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
struct LZ4_stream_t_internal {
LZ4_u32 hashTable[LZ4_HASH_SIZE_U32];
LZ4_u32 currentOffset;
LZ4_u32 tableType;
const LZ4_byte* dictionary;
const LZ4_stream_t_internal* dictCtx;
LZ4_u32 currentOffset;
LZ4_u32 tableType;
LZ4_u32 dictSize;
/* Implicit padding to ensure structure is aligned */
};
typedef struct {
const LZ4_byte* externalDict;
size_t extDictSize;
const LZ4_byte* prefixEnd;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
/*! LZ4_stream_t :
* Do not use below internal definitions directly !
* Declare or allocate an LZ4_stream_t instead.
* LZ4_stream_t can also be created using LZ4_createStream(), which is recommended.
* The structure definition can be convenient for static allocation
* (on stack, or as part of larger structure).
* Init this structure with LZ4_initStream() before first use.
* note : only use this definition in association with static linking !
* this definition is not API/ABI safe, and may change in future versions.
*/
#define LZ4_STREAMSIZE 16416 /* static size, for inter-version compatibility */
#define LZ4_STREAMSIZE_VOIDP (LZ4_STREAMSIZE / sizeof(void*))
#define LZ4_STREAM_MINSIZE ((1UL << LZ4_MEMORY_USAGE) + 32) /* static size, for inter-version compatibility */
union LZ4_stream_u {
void* table[LZ4_STREAMSIZE_VOIDP];
char minStateSize[LZ4_STREAM_MINSIZE];
LZ4_stream_t_internal internal_donotuse;
}; /* previously typedef'd to LZ4_stream_t */
@@ -641,21 +725,25 @@ union LZ4_stream_u {
* In which case, the function will @return NULL.
* Note2: An LZ4_stream_t structure guarantees correct alignment and size.
* Note3: Before v1.9.0, use LZ4_resetStream() instead
*/
**/
LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* buffer, size_t size);
/*! LZ4_streamDecode_t :
* information structure to track an LZ4 stream during decompression.
* init this structure using LZ4_setStreamDecode() before first use.
* note : only use in association with static linking !
* this definition is not API/ABI safe,
* and may change in a future version !
*/
#define LZ4_STREAMDECODESIZE_U64 (4 + ((sizeof(void*)==16) ? 2 : 0) /*AS-400*/ )
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
* Never ever use below internal definitions directly !
* These definitions are not API/ABI safe, and may change in future versions.
* If you need static allocation, declare or allocate an LZ4_streamDecode_t object.
**/
typedef struct {
const LZ4_byte* externalDict;
const LZ4_byte* prefixEnd;
size_t extDictSize;
size_t prefixSize;
} LZ4_streamDecode_t_internal;
#define LZ4_STREAMDECODE_MINSIZE 32
union LZ4_streamDecode_u {
unsigned long long table[LZ4_STREAMDECODESIZE_U64];
char minStateSize[LZ4_STREAMDECODE_MINSIZE];
LZ4_streamDecode_t_internal internal_donotuse;
} ; /* previously typedef'd to LZ4_streamDecode_t */
File diff suppressed because it is too large Load Diff
+413
View File
@@ -0,0 +1,413 @@
/*
LZ4 HC - High Compression Mode of LZ4
Header File
Copyright (C) 2011-2020, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You can contact the author at :
- LZ4 source repository : https://github.com/lz4/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/
#ifndef LZ4_HC_H_19834876238432
#define LZ4_HC_H_19834876238432
#if defined (__cplusplus)
extern "C" {
#endif
/* --- Dependency --- */
/* note : lz4hc requires lz4.h/lz4.c for compilation */
#include "lz4.h" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */
/* --- Useful constants --- */
#define LZ4HC_CLEVEL_MIN 3
#define LZ4HC_CLEVEL_DEFAULT 9
#define LZ4HC_CLEVEL_OPT_MIN 10
#define LZ4HC_CLEVEL_MAX 12
/*-************************************
* Block Compression
**************************************/
/*! LZ4_compress_HC() :
* Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm.
* `dst` must be already allocated.
* Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h")
* Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h")
* `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work.
* Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX.
* @return : the number of bytes written into 'dst'
* or 0 if compression fails.
*/
LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
/* Note :
* Decompression functions are provided within "lz4.h" (BSD license)
*/
/*! LZ4_compress_HC_extStateHC() :
* Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`.
* `state` size is provided by LZ4_sizeofStateHC().
* Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly).
*/
LZ4LIB_API int LZ4_sizeofStateHC(void);
LZ4LIB_API int LZ4_compress_HC_extStateHC(void* stateHC, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel);
/*! LZ4_compress_HC_destSize() : v1.9.0+
* Will compress as much data as possible from `src`
* to fit into `targetDstSize` budget.
* Result is provided in 2 parts :
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
* or 0 if compression fails.
* `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src`
*/
LZ4LIB_API int LZ4_compress_HC_destSize(void* stateHC,
const char* src, char* dst,
int* srcSizePtr, int targetDstSize,
int compressionLevel);
/*-************************************
* Streaming Compression
* Bufferless synchronous API
**************************************/
typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */
/*! LZ4_createStreamHC() and LZ4_freeStreamHC() :
* These functions create and release memory for LZ4 HC streaming state.
* Newly created states are automatically initialized.
* A same state can be used multiple times consecutively,
* starting with LZ4_resetStreamHC_fast() to start a new stream of blocks.
*/
LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void);
LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
/*
These functions compress data in successive blocks of any size,
using previous blocks as dictionary, to improve compression ratio.
One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks.
There is an exception for ring buffers, which can be smaller than 64 KB.
Ring-buffer scenario is automatically detected and handled within LZ4_compress_HC_continue().
Before starting compression, state must be allocated and properly initialized.
LZ4_createStreamHC() does both, though compression level is set to LZ4HC_CLEVEL_DEFAULT.
Selecting the compression level can be done with LZ4_resetStreamHC_fast() (starts a new stream)
or LZ4_setCompressionLevel() (anytime, between blocks in the same stream) (experimental).
LZ4_resetStreamHC_fast() only works on states which have been properly initialized at least once,
which is automatically the case when state is created using LZ4_createStreamHC().
After reset, a first "fictional block" can be designated as initial dictionary,
using LZ4_loadDictHC() (Optional).
Invoke LZ4_compress_HC_continue() to compress each successive block.
The number of blocks is unlimited.
Previous input blocks, including initial dictionary when present,
must remain accessible and unmodified during compression.
It's allowed to update compression level anytime between blocks,
using LZ4_setCompressionLevel() (experimental).
'dst' buffer should be sized to handle worst case scenarios
(see LZ4_compressBound(), it ensures compression success).
In case of failure, the API does not guarantee recovery,
so the state _must_ be reset.
To ensure compression success
whenever `dst` buffer size cannot be made >= LZ4_compressBound(),
consider using LZ4_compress_HC_continue_destSize().
Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks,
it's possible to copy the last blocks into a more stable memory space, using LZ4_saveDictHC().
Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer' (<= 64 KB)
After completing a streaming compression,
it's possible to start a new stream of blocks, using the same LZ4_streamHC_t state,
just by resetting it, using LZ4_resetStreamHC_fast().
*/
LZ4LIB_API void LZ4_resetStreamHC_fast(LZ4_streamHC_t* streamHCPtr, int compressionLevel); /* v1.9.0+ */
LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize);
LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr,
const char* src, char* dst,
int srcSize, int maxDstSize);
/*! LZ4_compress_HC_continue_destSize() : v1.9.0+
* Similar to LZ4_compress_HC_continue(),
* but will read as much data as possible from `src`
* to fit into `targetDstSize` budget.
* Result is provided into 2 parts :
* @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
* or 0 if compression fails.
* `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`.
* Note that this function may not consume the entire input.
*/
LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr,
const char* src, char* dst,
int* srcSizePtr, int targetDstSize);
LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
/*^**********************************************
* !!!!!! STATIC LINKING ONLY !!!!!!
***********************************************/
/*-******************************************************************
* PRIVATE DEFINITIONS :
* Do not use these definitions directly.
* They are merely exposed to allow static allocation of `LZ4_streamHC_t`.
* Declare an `LZ4_streamHC_t` directly, rather than any type below.
* Even then, only do so in the context of static linking, as definitions may change between versions.
********************************************************************/
#define LZ4HC_DICTIONARY_LOGSIZE 16
#define LZ4HC_MAXD (1<<LZ4HC_DICTIONARY_LOGSIZE)
#define LZ4HC_MAXD_MASK (LZ4HC_MAXD - 1)
#define LZ4HC_HASH_LOG 15
#define LZ4HC_HASHTABLESIZE (1 << LZ4HC_HASH_LOG)
#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
/* Never ever use these definitions directly !
* Declare or allocate an LZ4_streamHC_t instead.
**/
typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
struct LZ4HC_CCtx_internal
{
LZ4_u32 hashTable[LZ4HC_HASHTABLESIZE];
LZ4_u16 chainTable[LZ4HC_MAXD];
const LZ4_byte* end; /* next block here to continue on current prefix */
const LZ4_byte* prefixStart; /* Indexes relative to this position */
const LZ4_byte* dictStart; /* alternate reference for extDict */
LZ4_u32 dictLimit; /* below that point, need extDict */
LZ4_u32 lowLimit; /* below that point, no more dict */
LZ4_u32 nextToUpdate; /* index from which to continue dictionary update */
short compressionLevel;
LZ4_i8 favorDecSpeed; /* favor decompression speed if this flag set,
otherwise, favor compression ratio */
LZ4_i8 dirty; /* stream has to be fully reset if this flag is set */
const LZ4HC_CCtx_internal* dictCtx;
};
#define LZ4_STREAMHC_MINSIZE 262200 /* static size, for inter-version compatibility */
union LZ4_streamHC_u {
char minStateSize[LZ4_STREAMHC_MINSIZE];
LZ4HC_CCtx_internal internal_donotuse;
}; /* previously typedef'd to LZ4_streamHC_t */
/* LZ4_streamHC_t :
* This structure allows static allocation of LZ4 HC streaming state.
* This can be used to allocate statically on stack, or as part of a larger structure.
*
* Such state **must** be initialized using LZ4_initStreamHC() before first use.
*
* Note that invoking LZ4_initStreamHC() is not required when
* the state was created using LZ4_createStreamHC() (which is recommended).
* Using the normal builder, a newly created state is automatically initialized.
*
* Static allocation shall only be used in combination with static linking.
*/
/* LZ4_initStreamHC() : v1.9.0+
* Required before first use of a statically allocated LZ4_streamHC_t.
* Before v1.9.0 : use LZ4_resetStreamHC() instead
*/
LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC(void* buffer, size_t size);
/*-************************************
* Deprecated Functions
**************************************/
/* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */
/* deprecated compression functions */
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC (const char* source, char* dest, int inputSize);
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize);
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize);
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
/* Obsolete streaming functions; degraded functionality; do not use!
*
* In order to perform streaming compression, these functions depended on data
* that is no longer tracked in the state. They have been preserved as well as
* possible: using them will still produce a correct output. However, use of
* LZ4_slideInputBufferHC() will truncate the history of the stream, rather
* than preserve a window-sized chunk of history.
*/
#if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer);
LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data);
#endif
LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void);
LZ4_DEPRECATED("use LZ4_initStreamHC() instead") LZ4LIB_API int LZ4_resetStreamStateHC(void* state, char* inputBuffer);
/* LZ4_resetStreamHC() is now replaced by LZ4_initStreamHC().
* The intention is to emphasize the difference with LZ4_resetStreamHC_fast(),
* which is now the recommended function to start a new stream of blocks,
* but cannot be used to initialize a memory segment containing arbitrary garbage data.
*
* It is recommended to switch to LZ4_initStreamHC().
* LZ4_resetStreamHC() will generate deprecation warnings in a future version.
*/
LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel);
#if defined (__cplusplus)
}
#endif
#endif /* LZ4_HC_H_19834876238432 */
/*-**************************************************
* !!!!! STATIC LINKING ONLY !!!!!
* Following definitions are considered experimental.
* They should not be linked from DLL,
* as there is no guarantee of API stability yet.
* Prototypes will be promoted to "stable" status
* after successful usage in real-life scenarios.
***************************************************/
#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
#ifndef LZ4_HC_SLO_098092834
#define LZ4_HC_SLO_098092834
#define LZ4_STATIC_LINKING_ONLY /* LZ4LIB_STATIC_API */
#include "lz4.h"
#if defined (__cplusplus)
extern "C" {
#endif
/*! LZ4_setCompressionLevel() : v1.8.0+ (experimental)
* It's possible to change compression level
* between successive invocations of LZ4_compress_HC_continue*()
* for dynamic adaptation.
*/
LZ4LIB_STATIC_API void LZ4_setCompressionLevel(
LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
/*! LZ4_favorDecompressionSpeed() : v1.8.2+ (experimental)
* Opt. Parser will favor decompression speed over compression ratio.
* Only applicable to levels >= LZ4HC_CLEVEL_OPT_MIN.
*/
LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed(
LZ4_streamHC_t* LZ4_streamHCPtr, int favor);
/*! LZ4_resetStreamHC_fast() : v1.9.0+
* When an LZ4_streamHC_t is known to be in a internally coherent state,
* it can often be prepared for a new compression with almost no work, only
* sometimes falling back to the full, expensive reset that is always required
* when the stream is in an indeterminate state (i.e., the reset performed by
* LZ4_resetStreamHC()).
*
* LZ4_streamHCs are guaranteed to be in a valid state when:
* - returned from LZ4_createStreamHC()
* - reset by LZ4_resetStreamHC()
* - memset(stream, 0, sizeof(LZ4_streamHC_t))
* - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast()
* - the stream was in a valid state and was then used in any compression call
* that returned success
* - the stream was in an indeterminate state and was used in a compression
* call that fully reset the state (LZ4_compress_HC_extStateHC()) and that
* returned success
*
* Note:
* A stream that was last used in a compression call that returned an error
* may be passed to this function. However, it will be fully reset, which will
* clear any existing history and settings from the context.
*/
LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast(
LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
/*! LZ4_compress_HC_extStateHC_fastReset() :
* A variant of LZ4_compress_HC_extStateHC().
*
* Using this variant avoids an expensive initialization step. It is only safe
* to call if the state buffer is known to be correctly initialized already
* (see above comment on LZ4_resetStreamHC_fast() for a definition of
* "correctly initialized"). From a high level, the difference is that this
* function initializes the provided state with a call to
* LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a
* call to LZ4_resetStreamHC().
*/
LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset (
void* state,
const char* src, char* dst,
int srcSize, int dstCapacity,
int compressionLevel);
/*! LZ4_attach_HC_dictionary() :
* This is an experimental API that allows for the efficient use of a
* static dictionary many times.
*
* Rather than re-loading the dictionary buffer into a working context before
* each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
* working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
* in which the working stream references the dictionary stream in-place.
*
* Several assumptions are made about the state of the dictionary stream.
* Currently, only streams which have been prepared by LZ4_loadDictHC() should
* be expected to work.
*
* Alternatively, the provided dictionary stream pointer may be NULL, in which
* case any existing dictionary stream is unset.
*
* A dictionary should only be attached to a stream without any history (i.e.,
* a stream that has just been reset).
*
* The dictionary will remain attached to the working stream only for the
* current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
* dictionary context association from the working stream. The dictionary
* stream (and source buffer) must remain in-place / accessible / unchanged
* through the lifetime of the stream session.
*/
LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary(
LZ4_streamHC_t *working_stream,
const LZ4_streamHC_t *dictionary_stream);
#if defined (__cplusplus)
}
#endif
#endif /* LZ4_HC_SLO_098092834 */
#endif /* LZ4_HC_STATIC_LINKING_ONLY */