Skip to content

chore: add stride information in the image resource file - #5653

Merged
FASTSHIFT merged 4 commits into
lvgl:masterfrom
FASTSHIFT:chore_add_assets_image_stride
Feb 15, 2024
Merged

FASTSHIFT merged 4 commits into
lvgl:masterfrom
FASTSHIFT:chore_add_assets_image_stride

Conversation

@FASTSHIFT

@FASTSHIFT FASTSHIFT commented Feb 14, 2024 •

Copy link
Copy Markdown
Collaborator

Description of the feature or fix

Related discussion: #5471

Due to the large number of files, I used a script to automate the changes, which was written by ChatGPT:

import os
import re
import sys
import subprocess

def get_stride(w_value, cf_value):
    # 使用subprocess调用外部程序获取返回值
    command = f"./build/bin/main {w_value} {cf_value}"
    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    return result.stdout.strip()

def update_struct_content(struct_content, stride, h_value):
    # 添加新的字段 .header.stride
    updated_content = re.sub(r'(\.header\.h\s*=\s*\w+)', rf'\1,\n    .header.stride = {stride}', struct_content)
    return updated_content

def extract_fields_from_file(file_path):
    with open(file_path, 'r') as file:
        content = file.read()
        # 正则表达式匹配结构体
        matches = re.findall(r'const lv_image_dsc_t\s+(\w+)\s*=\s*{([^}]+)}', content, re.MULTILINE)
        for match in matches:
            struct_name = match[0]
            struct_content = match[1]
            # 提取所需字段
            cf_match = re.search(r'\.header\.cf\s*=\s*(\w+)', struct_content)
            w_match = re.search(r'\.header\.w\s*=\s*(\w+)', struct_content)
            h_match = re.search(r'\.header\.h\s*=\s*(\w+)', struct_content)
            if cf_match and w_match and h_match:
                cf_value = cf_match.group(1)
                w_value = w_match.group(1)
                h_value = h_match.group(1)
                # 调用外部程序
                stride = get_stride(int(w_value), cf_value)
                if(stride == "0"):
                    print(f"Error: Stride is 0 for struct {struct_name}")
                    continue

                # 更新原始文件内容
                updated_content = update_struct_content(struct_content, stride, h_value)
                # 写回到文件中
                updated_file_content = content.replace(struct_content, updated_content)
                with open(file_path, 'w') as updated_file:
                    updated_file.write(updated_file_content)
                print(f"For struct {struct_name}: Stride = {stride}")

def scan_and_extract_fields(directory):
    for root, _, files in os.walk(directory):
        for file in files:
            if file.endswith('.c'):
                file_path = os.path.join(root, file)
                extract_fields_from_file(file_path)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python script.py /path/to/your/directory")
        sys.exit(1)

    directory_path = sys.argv[1]
    if not os.path.isdir(directory_path):
        print("Invalid directory path.")
        sys.exit(1)

    scan_and_extract_fields(directory_path)

Working with this python script, there is also a C program(./build/bin/main) to ensure that the stride calculation is exactly the same as before:

static lv_color_format_t str2cf(const char* str)
{
#define CF_STR_CMP(CF)               \
    do {                             \
        if (strcmp(str, #CF) == 0) { \
            return CF;               \
        }                            \
    } while (0)

    CF_STR_CMP(LV_COLOR_FORMAT_RAW);
    CF_STR_CMP(LV_COLOR_FORMAT_RAW_ALPHA);
    CF_STR_CMP(LV_COLOR_FORMAT_L8);
    CF_STR_CMP(LV_COLOR_FORMAT_I1);
    CF_STR_CMP(LV_COLOR_FORMAT_I2);
    CF_STR_CMP(LV_COLOR_FORMAT_I4);
    CF_STR_CMP(LV_COLOR_FORMAT_I8);
    CF_STR_CMP(LV_COLOR_FORMAT_A8);
    CF_STR_CMP(LV_COLOR_FORMAT_RGB565);
    CF_STR_CMP(LV_COLOR_FORMAT_ARGB8565);
    CF_STR_CMP(LV_COLOR_FORMAT_RGB565A8);
    CF_STR_CMP(LV_COLOR_FORMAT_RGB888);
    CF_STR_CMP(LV_COLOR_FORMAT_ARGB8888);
    CF_STR_CMP(LV_COLOR_FORMAT_XRGB8888);
    CF_STR_CMP(LV_COLOR_FORMAT_A1);
    CF_STR_CMP(LV_COLOR_FORMAT_A2);
    CF_STR_CMP(LV_COLOR_FORMAT_A4);
    CF_STR_CMP(LV_COLOR_FORMAT_YUV_START);
    CF_STR_CMP(LV_COLOR_FORMAT_I420);
    CF_STR_CMP(LV_COLOR_FORMAT_I422);
    CF_STR_CMP(LV_COLOR_FORMAT_I444);
    CF_STR_CMP(LV_COLOR_FORMAT_I400);
    CF_STR_CMP(LV_COLOR_FORMAT_NV21);
    CF_STR_CMP(LV_COLOR_FORMAT_NV12);
    CF_STR_CMP(LV_COLOR_FORMAT_YUY2);
    CF_STR_CMP(LV_COLOR_FORMAT_UYVY);

    return LV_COLOR_FORMAT_UNKNOWN;
}

void img_stride_calc(int argc, const char* argv[])
{
    if (argc < 3) {
        printf("Usage: %s <width>\n", argv[0]);
        return;
    }
    int w = atoi(argv[1]);
    lv_color_format_t cf = str2cf(argv[2]);
    uint32_t stride = lv_draw_buf_width_to_stride(w, cf);
    printf("%d\n", stride);
}

int main(int argc, const char* argv[])
{
    /*Initialize LVGL*/
    lv_init();

    img_stride_calc(argc, argv);

    return 0;
}

Notes

@kisvegabor

Copy link
Copy Markdown
Member

Cool! 😎

The result looks good, but I can't see what ./build/bin/main is in get_stride. Could you tell that?

@FASTSHIFT

Copy link
Copy Markdown
Collaborator Author

Cool! 😎

The result looks good, but I can't see what ./build/bin/main is in get_stride. Could you tell that?

./build/bin/main is the C program mentioned above, which directly uses lvgl's lv_draw_buf_width_to_stride to calculate stride.

@FASTSHIFT
FASTSHIFT merged commit aad5a32 into lvgl:master Feb 15, 2024
@FASTSHIFT
FASTSHIFT deleted the chore_add_assets_image_stride branch February 15, 2024 04:03
HongChao6 pushed a commit to HongChao6/lvgl that referenced this pull request Oct 18, 2024
Signed-off-by: FASTSHIFT <vifextech@foxmail.com>
HongChao6 pushed a commit to HongChao6/lvgl that referenced this pull request Oct 18, 2024
Signed-off-by: FASTSHIFT <vifextech@foxmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants