10466543cSWenping Zhang /* 20466543cSWenping Zhang * (C) Copyright 2020 Rockchip Electronics Co., Ltd 30466543cSWenping Zhang * 40466543cSWenping Zhang * SPDX-License-Identifier: GPL-2.0+ 50466543cSWenping Zhang * Author: Wenping Zhang <wenping.zhang@rock-chips.com> 60466543cSWenping Zhang */ 70466543cSWenping Zhang 80466543cSWenping Zhang #include <stdio.h> 90466543cSWenping Zhang #include <stdlib.h> 100466543cSWenping Zhang #include <string.h> 110466543cSWenping Zhang #include <rk_eink.h> 120466543cSWenping Zhang 130466543cSWenping Zhang struct bmp_header { 140466543cSWenping Zhang /* Header */ 150466543cSWenping Zhang char signature[2]; 160466543cSWenping Zhang uint32_t file_size; 170466543cSWenping Zhang uint32_t reserved; 180466543cSWenping Zhang uint32_t data_offset; 190466543cSWenping Zhang /* InfoHeader */ 200466543cSWenping Zhang uint32_t size; 210466543cSWenping Zhang uint32_t width; 220466543cSWenping Zhang uint32_t height; 230466543cSWenping Zhang uint16_t planes; 240466543cSWenping Zhang uint16_t bit_count; 250466543cSWenping Zhang uint32_t compression; 260466543cSWenping Zhang uint32_t image_size; 270466543cSWenping Zhang uint32_t x_pixels_per_m; 280466543cSWenping Zhang uint32_t y_pixels_per_m; 290466543cSWenping Zhang uint32_t colors_used; 300466543cSWenping Zhang uint32_t colors_important; 310466543cSWenping Zhang /* ColorTable */ 320466543cSWenping Zhang } __attribute__((packed)); 330466543cSWenping Zhang 340466543cSWenping Zhang struct bmp_image { 350466543cSWenping Zhang struct bmp_header hdr; 360466543cSWenping Zhang uint8_t color_table[0]; 370466543cSWenping Zhang }; 380466543cSWenping Zhang 390466543cSWenping Zhang struct pixel_u16 { 400466543cSWenping Zhang uint16_t blue : 4, 410466543cSWenping Zhang green : 4, 420466543cSWenping Zhang red : 4, 430466543cSWenping Zhang alpha : 4; 440466543cSWenping Zhang } __attribute__((packed)); 450466543cSWenping Zhang 460466543cSWenping Zhang struct pixel_u24 { 470466543cSWenping Zhang uint8_t blue; 480466543cSWenping Zhang uint8_t green; 490466543cSWenping Zhang uint8_t red; 500466543cSWenping Zhang } __attribute__((packed)); 510466543cSWenping Zhang 520466543cSWenping Zhang struct pixel_u32 { 530466543cSWenping Zhang uint8_t blue; 540466543cSWenping Zhang uint8_t green; 550466543cSWenping Zhang uint8_t red; 560466543cSWenping Zhang uint8_t alpha; 570466543cSWenping Zhang } __attribute__((packed)); 580466543cSWenping Zhang 590466543cSWenping Zhang //logo partition Header, 64byte 600466543cSWenping Zhang struct logo_part_header { 610466543cSWenping Zhang char magic[4]; /* must be "RKEL" */ 620466543cSWenping Zhang uint32_t totoal_size; 630466543cSWenping Zhang uint32_t screen_width; 640466543cSWenping Zhang uint32_t screen_height; 650466543cSWenping Zhang uint32_t logo_count; 660466543cSWenping Zhang char version[4]; 670466543cSWenping Zhang uint32_t rsv[10]; 680466543cSWenping Zhang } __attribute__((packed)); 690466543cSWenping Zhang 700466543cSWenping Zhang // logo image header,32 byte 710466543cSWenping Zhang struct grayscale_header { 720466543cSWenping Zhang char magic[4]; /* must be "GR04" */ 730466543cSWenping Zhang uint16_t x; 740466543cSWenping Zhang uint16_t y; 750466543cSWenping Zhang uint16_t w; 760466543cSWenping Zhang uint16_t h; 770466543cSWenping Zhang uint32_t logo_type; 780466543cSWenping Zhang uint32_t data_offset; /* image offset in byte */ 790466543cSWenping Zhang uint32_t data_size; /* image size in byte */ 800466543cSWenping Zhang uint32_t rsv[2]; 810466543cSWenping Zhang } __attribute__((packed)); 820466543cSWenping Zhang 830466543cSWenping Zhang /* 840466543cSWenping Zhang * The start address of logo image in logo.img must be aligned 850466543cSWenping Zhang * in 512 bytes,so the header size must be times of 512 bytes. 860466543cSWenping Zhang * Here we fix the size to 512 bytes, so the count of logo image 870466543cSWenping Zhang * can only support up to 14. 880466543cSWenping Zhang */ 890466543cSWenping Zhang struct logo_info { 900466543cSWenping Zhang struct logo_part_header part_hdr; 910466543cSWenping Zhang struct grayscale_header img_hdr[14]; 920466543cSWenping Zhang } __attribute__((packed)); 930466543cSWenping Zhang 940466543cSWenping Zhang struct input_img_info { 950466543cSWenping Zhang char path[256]; 960466543cSWenping Zhang int logo_type; 970466543cSWenping Zhang }; 980466543cSWenping Zhang 990466543cSWenping Zhang /* 1000466543cSWenping Zhang * Every part of logo.img must be aligned in RK_BLK_SIZE, 1010466543cSWenping Zhang * use macro aligned_in_blk to calculate the the real size 1020466543cSWenping Zhang */ 1030466543cSWenping Zhang #define RK_BLK_SIZE 512 1040466543cSWenping Zhang #define ALIGN(x, y) (((x) + (y) - 1) & ~((y) - 1)) 1050466543cSWenping Zhang 1060466543cSWenping Zhang struct input_img_info in_img_info[16]; 1070466543cSWenping Zhang uint32_t screen_w; 1080466543cSWenping Zhang uint32_t screen_h; 1090466543cSWenping Zhang static const char version[4] = "1.00"; 1100466543cSWenping Zhang static const char *PROG; 1110466543cSWenping Zhang 1120466543cSWenping Zhang static const char *fix_path(const char *path) 1130466543cSWenping Zhang { 1140466543cSWenping Zhang if (!memcmp(path, "./", 2)) 1150466543cSWenping Zhang return path + 2; 1160466543cSWenping Zhang return path; 1170466543cSWenping Zhang } 1180466543cSWenping Zhang 1190466543cSWenping Zhang static void print_version(void) 1200466543cSWenping Zhang { 1210466543cSWenping Zhang printf("Version %s (zwp@rock-chips.com)\n", version); 1220466543cSWenping Zhang } 1230466543cSWenping Zhang 1240466543cSWenping Zhang void usage(void) 1250466543cSWenping Zhang { 1260466543cSWenping Zhang printf("Usage: %s [options] [arguments]\n\n", PROG); 1270466543cSWenping Zhang print_version(); 1280466543cSWenping Zhang printf("\t --uboot-logo path"); 1290466543cSWenping Zhang printf("\t\t\t Pack uboot logo to logo.img from given path\n"); 1300466543cSWenping Zhang printf("\t --charge-logo path"); 1310466543cSWenping Zhang printf("\t\t\t Pack charge logo to logo.img from given path\n"); 1320466543cSWenping Zhang printf("\t --lowpower-logo path"); 1330466543cSWenping Zhang printf("\t\t\t Pack low power logo to logo.img from given path\n"); 1340466543cSWenping Zhang printf("\t --kernel-logo path"); 1350466543cSWenping Zhang printf("\t\t\t Pack low power logo to logo.img from given path\n"); 1360466543cSWenping Zhang printf("\t --output path"); 1370466543cSWenping Zhang printf("\t\t\t Output the grayscale image to path\n"); 1380466543cSWenping Zhang } 1390466543cSWenping Zhang 1400466543cSWenping Zhang static inline int size_of_header(void) 1410466543cSWenping Zhang { 1420466543cSWenping Zhang return ALIGN(sizeof(struct logo_info), RK_BLK_SIZE); 1430466543cSWenping Zhang } 1440466543cSWenping Zhang 1450466543cSWenping Zhang static inline int size_of_one_image(void) 1460466543cSWenping Zhang { 1470466543cSWenping Zhang return ALIGN((screen_w * screen_h) >> 1, RK_BLK_SIZE); 1480466543cSWenping Zhang } 1490466543cSWenping Zhang 1500466543cSWenping Zhang int get_logo_resolution(char *in_path, uint32_t *logo_width, 1510466543cSWenping Zhang uint32_t *logo_height) 1520466543cSWenping Zhang { 1530466543cSWenping Zhang struct bmp_header bmp_hdr; 1540466543cSWenping Zhang FILE *file; 1550466543cSWenping Zhang int size; 1560466543cSWenping Zhang int ret = 0; 1570466543cSWenping Zhang 1580466543cSWenping Zhang if (!in_path) 1590466543cSWenping Zhang fprintf(stderr, "Invalid bmp file path.\n"); 1600466543cSWenping Zhang 1610466543cSWenping Zhang file = fopen(in_path, "rb"); 1620466543cSWenping Zhang if (!file) { 1630466543cSWenping Zhang fprintf(stderr, "File %s open failed.\n", in_path); 1640466543cSWenping Zhang return -1; 1650466543cSWenping Zhang } 1660466543cSWenping Zhang size = sizeof(struct bmp_header); 1670466543cSWenping Zhang if (size != fread(&bmp_hdr, 1, size, file)) { 1680466543cSWenping Zhang fprintf(stderr, "Incomplete read of file %s.\n", in_path); 1690466543cSWenping Zhang ret = -1; 1700466543cSWenping Zhang goto out; 1710466543cSWenping Zhang } 1720466543cSWenping Zhang if (!(bmp_hdr.signature[0] == 'B' && 1730466543cSWenping Zhang bmp_hdr.signature[1] == 'M')) { 1740466543cSWenping Zhang printf("cat not find bmp file\n"); 1750466543cSWenping Zhang ret = -1; 1760466543cSWenping Zhang goto out; 1770466543cSWenping Zhang } 1780466543cSWenping Zhang *logo_width = bmp_hdr.width; 1790466543cSWenping Zhang *logo_height = bmp_hdr.height; 1800466543cSWenping Zhang fprintf(stderr, "logo resolution is %d x %d.\n", 1810466543cSWenping Zhang *logo_width, *logo_height); 1820466543cSWenping Zhang out: 1830466543cSWenping Zhang fclose(file); 1840466543cSWenping Zhang return ret; 1850466543cSWenping Zhang } 1860466543cSWenping Zhang 1870466543cSWenping Zhang /* 1880466543cSWenping Zhang * The bmp pixel is scan from left-bottom to right-top 1890466543cSWenping Zhang */ 1900466543cSWenping Zhang int convert_bmp_idx_to_gray_idx(int idx, uint32_t w, uint32_t h) 1910466543cSWenping Zhang { 1920466543cSWenping Zhang int row = h - (idx / w) - 1; 1930466543cSWenping Zhang 1940466543cSWenping Zhang return (row * w + idx % w) / 2; 1950466543cSWenping Zhang } 1960466543cSWenping Zhang 1970466543cSWenping Zhang int convert_one_image(char *in_path, void *out_buf, uint32_t offset, 1980466543cSWenping Zhang struct grayscale_header *gr_hdr, int type) 1990466543cSWenping Zhang { 2000466543cSWenping Zhang struct bmp_image *bmp; 2010466543cSWenping Zhang struct bmp_header *bmp_hdr; 2020466543cSWenping Zhang FILE *file; 2030466543cSWenping Zhang void *bmp_buf; 2040466543cSWenping Zhang int size; 2050466543cSWenping Zhang int ret = -1; 2060466543cSWenping Zhang uint8_t *gr16_data = (uint8_t *)out_buf; 2070466543cSWenping Zhang 2080466543cSWenping Zhang if (!out_buf || !in_path) { 2090466543cSWenping Zhang fprintf(stderr, "in_path or out_buf is NULL.\n"); 2100466543cSWenping Zhang return -1; 2110466543cSWenping Zhang } 2120466543cSWenping Zhang 2130466543cSWenping Zhang file = fopen(in_path, "rb"); 2140466543cSWenping Zhang if (!file) { 2150466543cSWenping Zhang fprintf(stderr, "File %s open failed.\n", in_path); 2160466543cSWenping Zhang return -1; 2170466543cSWenping Zhang } 2180466543cSWenping Zhang 2190466543cSWenping Zhang fseek(file, 0, SEEK_END); 2200466543cSWenping Zhang size = ftell(file); 2210466543cSWenping Zhang fseek(file, 0, SEEK_SET); 2220466543cSWenping Zhang 2230466543cSWenping Zhang bmp_buf = calloc(1, size); 2240466543cSWenping Zhang if (!bmp_buf) { 2250466543cSWenping Zhang fprintf(stderr, "Allocate memory of %d bytes failed.\n", size); 2260466543cSWenping Zhang fclose(file); 2270466543cSWenping Zhang return -1; 2280466543cSWenping Zhang } 2290466543cSWenping Zhang if (size != fread(bmp_buf, 1, size, file)) { 2300466543cSWenping Zhang fprintf(stderr, "Incomplete read of file %s.\n", in_path); 2310466543cSWenping Zhang goto out; 2320466543cSWenping Zhang } 2330466543cSWenping Zhang 2340466543cSWenping Zhang bmp = (struct bmp_image *)bmp_buf; 2350466543cSWenping Zhang bmp_hdr = &bmp->hdr; 2360466543cSWenping Zhang if (!(bmp_hdr->signature[0] == 'B' && 2370466543cSWenping Zhang bmp_hdr->signature[1] == 'M')) { 2380466543cSWenping Zhang printf("cat not find bmp file\n"); 2390466543cSWenping Zhang goto out; 2400466543cSWenping Zhang } 2410466543cSWenping Zhang 2420466543cSWenping Zhang if (size != le32_to_cpu(bmp_hdr->file_size)) { 2430466543cSWenping Zhang fprintf(stderr, "Invalid BMP file size %d.\n", 2440466543cSWenping Zhang le32_to_cpu(bmp_hdr->file_size)); 2450466543cSWenping Zhang goto out; 2460466543cSWenping Zhang } 2470466543cSWenping Zhang printf("bmp_hdr->width=%d, bmp_hdr->height=%d\n", 2480466543cSWenping Zhang bmp_hdr->width, bmp_hdr->height); 2490466543cSWenping Zhang printf("screen_w=%d, screen_h=%d\n", screen_w, screen_h); 2500466543cSWenping Zhang if (le32_to_cpu(bmp_hdr->width) != screen_w || 2510466543cSWenping Zhang le32_to_cpu(bmp_hdr->height) != screen_h) { 2520466543cSWenping Zhang fprintf(stderr, "The image size must same with others.\n"); 2530466543cSWenping Zhang goto out; 2540466543cSWenping Zhang } 2550466543cSWenping Zhang //write header 2560466543cSWenping Zhang gr_hdr->magic[0] = 'G'; 2570466543cSWenping Zhang gr_hdr->magic[1] = 'R'; 2580466543cSWenping Zhang gr_hdr->magic[2] = '0'; 2590466543cSWenping Zhang gr_hdr->magic[3] = '4'; 2600466543cSWenping Zhang gr_hdr->x = 0; 2610466543cSWenping Zhang gr_hdr->y = 0; 2620466543cSWenping Zhang gr_hdr->w = screen_w; 2630466543cSWenping Zhang gr_hdr->h = screen_h; 2640466543cSWenping Zhang gr_hdr->logo_type = type; 2650466543cSWenping Zhang gr_hdr->data_offset = offset; 2660466543cSWenping Zhang gr_hdr->data_size = screen_w * screen_h / 2; 2670466543cSWenping Zhang 2680466543cSWenping Zhang printf("bmp depth is %d\n", bmp_hdr->bit_count); 2690466543cSWenping Zhang //convert rgb to gray data, and write to output buffer 2700466543cSWenping Zhang // the used algorithm please refer to below url: 2710466543cSWenping Zhang // https://www.cnblogs.com/zhangjiansheng/p/6925722.html 2720466543cSWenping Zhang // we use below algorithm: 2730466543cSWenping Zhang // Gray = (R*19595 + G*38469 + B*7472) >> 16 2740466543cSWenping Zhang switch (bmp_hdr->bit_count) { 2750466543cSWenping Zhang case 16:{ 2760466543cSWenping Zhang struct pixel_u16 *color_u16; 2770466543cSWenping Zhang int i; 2780466543cSWenping Zhang 2790466543cSWenping Zhang color_u16 = (struct pixel_u16 *)bmp->color_table; 2800466543cSWenping Zhang for (i = 0; i < screen_w * screen_h / 2; i++) { 2810466543cSWenping Zhang struct pixel_u16 *pix1 = &color_u16[2 * i]; 2820466543cSWenping Zhang struct pixel_u16 *pix2 = &color_u16[2 * i + 1]; 2830466543cSWenping Zhang int j = convert_bmp_idx_to_gray_idx(2 * i, screen_w, 2840466543cSWenping Zhang screen_h); 2850466543cSWenping Zhang /* 2860466543cSWenping Zhang * the rgb value of pixel_u16 is 4 bits, 2870466543cSWenping Zhang * so the counted grayscale value is 4bit 2880466543cSWenping Zhang */ 2890466543cSWenping Zhang uint32_t gray_px1 = (pix1->red * 19595 + 2900466543cSWenping Zhang pix1->green * 38469 + 2910466543cSWenping Zhang pix1->blue * 7472) >> 16; 2920466543cSWenping Zhang uint32_t gray_px2 = (pix2->red * 19595 + 2930466543cSWenping Zhang pix2->green * 38469 + 2940466543cSWenping Zhang pix2->blue * 7472) >> 16; 2950466543cSWenping Zhang gr16_data[j] = gray_px1 | (gray_px2 << 4); 2960466543cSWenping Zhang } 2970466543cSWenping Zhang } 2980466543cSWenping Zhang break; 2990466543cSWenping Zhang case 24: { 3000466543cSWenping Zhang struct pixel_u24 *color_u24; 3010466543cSWenping Zhang int i; 3020466543cSWenping Zhang 3030466543cSWenping Zhang color_u24 = (struct pixel_u24 *)bmp->color_table; 3040466543cSWenping Zhang for (i = 0; i < screen_w * screen_h / 2; i++) { 3050466543cSWenping Zhang struct pixel_u24 *pix1 = &color_u24[2 * i]; 3060466543cSWenping Zhang struct pixel_u24 *pix2 = &color_u24[2 * i + 1]; 3070466543cSWenping Zhang int j = convert_bmp_idx_to_gray_idx(2 * i, screen_w, 3080466543cSWenping Zhang screen_h); 3090466543cSWenping Zhang /* 3100466543cSWenping Zhang * The rgb value of pixel_u24 is 8 bits, 3110466543cSWenping Zhang * so the counted grayscale 3120466543cSWenping Zhang * value need to divide into 16 3130466543cSWenping Zhang */ 3140466543cSWenping Zhang uint32_t gray_px1 = ((pix1->red * 19595 + 3150466543cSWenping Zhang pix1->green * 38469 + 3160466543cSWenping Zhang pix1->blue * 7472) >> 16) >> 4; 3170466543cSWenping Zhang uint32_t gray_px2 = ((pix2->red * 19595 + 3180466543cSWenping Zhang pix2->green * 38469 + 3190466543cSWenping Zhang pix2->blue * 7472) >> 16) >> 4; 3200466543cSWenping Zhang 3210466543cSWenping Zhang gr16_data[j] = gray_px1 | (gray_px2 << 4); 3220466543cSWenping Zhang } 3230466543cSWenping Zhang } 3240466543cSWenping Zhang break; 3250466543cSWenping Zhang case 32: { 3260466543cSWenping Zhang struct pixel_u32 *color_u32; 3270466543cSWenping Zhang int i; 3280466543cSWenping Zhang 3290466543cSWenping Zhang color_u32 = (struct pixel_u32 *)bmp->color_table; 3300466543cSWenping Zhang for (i = 0; i < screen_w * screen_h / 2; i++) { 3310466543cSWenping Zhang struct pixel_u32 *pix1 = &color_u32[2 * i]; 3320466543cSWenping Zhang struct pixel_u32 *pix2 = &color_u32[2 * i + 1]; 3330466543cSWenping Zhang int j = convert_bmp_idx_to_gray_idx(2 * i, screen_w, 3340466543cSWenping Zhang screen_h); 3350466543cSWenping Zhang /* 3360466543cSWenping Zhang * The rgb value of pixel_u32 is 8 bits, 3370466543cSWenping Zhang * so the counted grayscale 3380466543cSWenping Zhang * value need to divide into 16 3390466543cSWenping Zhang */ 3400466543cSWenping Zhang uint32_t gray_px1 = ((pix1->red * 19595 + 3410466543cSWenping Zhang pix1->green * 38469 + 3420466543cSWenping Zhang pix1->blue * 7472) >> 16) >> 4; 3430466543cSWenping Zhang uint32_t gray_px2 = ((pix2->red * 19595 + 3440466543cSWenping Zhang pix2->green * 38469 + 3450466543cSWenping Zhang pix2->blue * 7472) >> 16) >> 4; 3460466543cSWenping Zhang gr16_data[j] = gray_px1 | (gray_px2 << 4); 3470466543cSWenping Zhang } 3480466543cSWenping Zhang } 3490466543cSWenping Zhang break; 3500466543cSWenping Zhang default: 3510466543cSWenping Zhang ret = -1; 3520466543cSWenping Zhang printf("Invalid bit count[%d],only support 16/24/32 bpp bmp\n", 3530466543cSWenping Zhang bmp_hdr->bit_count); 3540466543cSWenping Zhang break; 3550466543cSWenping Zhang } 3560466543cSWenping Zhang 3570466543cSWenping Zhang fprintf(stderr, "Convert image success\n"); 3580466543cSWenping Zhang ret = 0; 3590466543cSWenping Zhang out: 3600466543cSWenping Zhang free(bmp_buf); 3610466543cSWenping Zhang fclose(file); 3620466543cSWenping Zhang return ret; 3630466543cSWenping Zhang } 3640466543cSWenping Zhang 365*e091b6c9SWenping Zhang void *init_grayscale_logo_buf(int logo_count, uint32_t size_one_image) 3660466543cSWenping Zhang { 3670466543cSWenping Zhang int size; 3680466543cSWenping Zhang void *out_buf; 3690466543cSWenping Zhang 3700466543cSWenping Zhang if (!logo_count) { 3710466543cSWenping Zhang fprintf(stderr, "No input logo!\n"); 3720466543cSWenping Zhang return NULL; 3730466543cSWenping Zhang } 3740466543cSWenping Zhang size = size_of_header(); 3750466543cSWenping Zhang fprintf(stderr, "size of header in logo.img is %d\n", size); 3760466543cSWenping Zhang //every pixel of the grayscale image is 4 bits 377*e091b6c9SWenping Zhang size += logo_count * size_one_image; 3780466543cSWenping Zhang out_buf = calloc(1, size); 3790466543cSWenping Zhang 3800466543cSWenping Zhang return out_buf; 3810466543cSWenping Zhang } 3820466543cSWenping Zhang 3830466543cSWenping Zhang void deinit_grayscale_logo_buf(void *buf) 3840466543cSWenping Zhang { 3850466543cSWenping Zhang if (buf) { 3860466543cSWenping Zhang free(buf); 3870466543cSWenping Zhang buf = NULL; 3880466543cSWenping Zhang } 3890466543cSWenping Zhang } 3900466543cSWenping Zhang 3910466543cSWenping Zhang int main(int argc, char *argv[]) 3920466543cSWenping Zhang { 3930466543cSWenping Zhang char out_path[256] = {0}; 3940466543cSWenping Zhang void *out_buf; 3950466543cSWenping Zhang int logo_count = 0; 3960466543cSWenping Zhang int i; 3970466543cSWenping Zhang int hdr_size, one_img_size, total_size; 3980466543cSWenping Zhang int ret = -1; 3990466543cSWenping Zhang struct logo_info *logo_hdr; 4000466543cSWenping Zhang FILE *file; 4010466543cSWenping Zhang 4020466543cSWenping Zhang PROG = fix_path(argv[0]); 4030466543cSWenping Zhang 4040466543cSWenping Zhang argc--, argv++; 4050466543cSWenping Zhang while (argc > 0 && argv[0][0] == '-') { 4060466543cSWenping Zhang /* it's a opt arg. */ 4070466543cSWenping Zhang const char *arg = argv[0]; 4080466543cSWenping Zhang 4090466543cSWenping Zhang argc--, argv++; 4100466543cSWenping Zhang if (!strcmp("-h", arg)) { 4110466543cSWenping Zhang usage(); 4120466543cSWenping Zhang return 0; 4130466543cSWenping Zhang } else if (!strcmp("--charge-logo", arg)) { 4140466543cSWenping Zhang int len, i; 4150466543cSWenping Zhang /* 4160466543cSWenping Zhang * Charge logo are located in directory 4170466543cSWenping Zhang * u-boot/tools/images/eink/, there are 7 4180466543cSWenping Zhang * pictures to tell user the battery capacity 4190466543cSWenping Zhang * during charging 4200466543cSWenping Zhang */ 4210466543cSWenping Zhang for (i = 0; i < 7; i++) { 4220466543cSWenping Zhang int logo_type = EINK_LOGO_CHARGING_0 << i; 4230466543cSWenping Zhang 4240466543cSWenping Zhang len = strlen(argv[0]); 4250466543cSWenping Zhang if (len > 256) { 4260466543cSWenping Zhang fprintf(stderr, 4270466543cSWenping Zhang "input charging logo path %s is too long.\n", 4280466543cSWenping Zhang argv[0]); 4290466543cSWenping Zhang return -1; 4300466543cSWenping Zhang } 4310466543cSWenping Zhang printf("charge logo path %s\n", argv[0]); 4320466543cSWenping Zhang memcpy(in_img_info[logo_count].path, 4330466543cSWenping Zhang argv[0], len); 4340466543cSWenping Zhang in_img_info[logo_count].logo_type = logo_type; 4350466543cSWenping Zhang logo_count++; 4360466543cSWenping Zhang argc--, argv++; 4370466543cSWenping Zhang } 4380466543cSWenping Zhang } else if (!strcmp("--uboot-logo", arg)) { 4390466543cSWenping Zhang int len = strlen(argv[0]); 4400466543cSWenping Zhang 4410466543cSWenping Zhang if (len > 256) { 4420466543cSWenping Zhang printf("Uboot logo path %s is too long.\n", 4430466543cSWenping Zhang argv[0]); 4440466543cSWenping Zhang return -1; 4450466543cSWenping Zhang } 4460466543cSWenping Zhang memcpy(in_img_info[logo_count].path, argv[0], len); 4470466543cSWenping Zhang in_img_info[logo_count].logo_type = EINK_LOGO_UBOOT; 4480466543cSWenping Zhang logo_count++; 4490466543cSWenping Zhang argc--, argv++; 4500466543cSWenping Zhang } else if (!strcmp("--kernel-logo", arg)) { 4510466543cSWenping Zhang int len = strlen(argv[0]); 4520466543cSWenping Zhang 4530466543cSWenping Zhang if (len > 256) { 4540466543cSWenping Zhang printf("Kernel logo path %s is too long\n", 4550466543cSWenping Zhang argv[0]); 4560466543cSWenping Zhang return -1; 4570466543cSWenping Zhang } 4580466543cSWenping Zhang memcpy(in_img_info[logo_count].path, argv[0], len); 4590466543cSWenping Zhang in_img_info[logo_count].logo_type = EINK_LOGO_KERNEL; 4600466543cSWenping Zhang logo_count++; 4610466543cSWenping Zhang argc--, argv++; 4620466543cSWenping Zhang } else if (!strcmp("--screen-width", arg)) { 4630466543cSWenping Zhang screen_w = strtoul(argv[0], NULL, 10); 4640466543cSWenping Zhang argc--, argv++; 4650466543cSWenping Zhang } else if (!strcmp("--screen-height", arg)) { 4660466543cSWenping Zhang screen_h = strtoul(argv[0], NULL, 10); 4670466543cSWenping Zhang argc--, argv++; 4680466543cSWenping Zhang } else if (!strcmp("--output", arg)) { 4690466543cSWenping Zhang int len = strlen(argv[0]); 4700466543cSWenping Zhang 4710466543cSWenping Zhang if (len > 256) { 4720466543cSWenping Zhang printf("input output path %s is too long.\n", 4730466543cSWenping Zhang argv[0]); 4740466543cSWenping Zhang return -1; 4750466543cSWenping Zhang } 4760466543cSWenping Zhang memcpy(out_path, argv[0], len); 4770466543cSWenping Zhang argc--, argv++; 4780466543cSWenping Zhang } else { 4790466543cSWenping Zhang fprintf(stderr, "Unknown opt:%s", arg); 4800466543cSWenping Zhang usage(); 4810466543cSWenping Zhang return -1; 4820466543cSWenping Zhang } 4830466543cSWenping Zhang } 4840466543cSWenping Zhang 4850466543cSWenping Zhang ret = get_logo_resolution(in_img_info[0].path, &screen_w, &screen_h); 4860466543cSWenping Zhang if (ret < 0) { 4870466543cSWenping Zhang fprintf(stderr, 4880466543cSWenping Zhang "Get height and width from logo image failed.\n"); 4890466543cSWenping Zhang usage(); 4900466543cSWenping Zhang return -1; 4910466543cSWenping Zhang } 4920466543cSWenping Zhang 4930466543cSWenping Zhang if (screen_w == 0 || screen_h == 0) { 4940466543cSWenping Zhang fprintf(stderr, 4950466543cSWenping Zhang "The screen weight and screen height must be set.\n"); 4960466543cSWenping Zhang usage(); 4970466543cSWenping Zhang return -1; 4980466543cSWenping Zhang } 4990466543cSWenping Zhang 5000466543cSWenping Zhang file = fopen(out_path, "wb+"); 5010466543cSWenping Zhang if (!file) { 5020466543cSWenping Zhang fprintf(stderr, "File %s open failed.\n", out_path); 5030466543cSWenping Zhang usage(); 5040466543cSWenping Zhang return -1; 5050466543cSWenping Zhang } 506*e091b6c9SWenping Zhang hdr_size = size_of_header(); 507*e091b6c9SWenping Zhang one_img_size = size_of_one_image(); 5080466543cSWenping Zhang 509*e091b6c9SWenping Zhang out_buf = init_grayscale_logo_buf(logo_count, one_img_size); 5100466543cSWenping Zhang if (!out_buf) { 5110466543cSWenping Zhang fprintf(stderr, "Can't malloc buffer for grayscale image.\n"); 5120466543cSWenping Zhang fclose(file); 5130466543cSWenping Zhang return -1; 5140466543cSWenping Zhang } 5150466543cSWenping Zhang 5160466543cSWenping Zhang logo_hdr = (struct logo_info *)out_buf; 5170466543cSWenping Zhang fprintf(stderr, "logo count is %d,one_img_size=%d,size=%d.\n", 5180466543cSWenping Zhang logo_count, one_img_size, screen_w * screen_h / 2); 5190466543cSWenping Zhang for (i = 0; i < logo_count; i++) { 5200466543cSWenping Zhang char *in_path = in_img_info[i].path; 5210466543cSWenping Zhang int type = in_img_info[i].logo_type; 5220466543cSWenping Zhang void *img_buf; 5230466543cSWenping Zhang int offset = hdr_size + i * one_img_size; 5240466543cSWenping Zhang 5250466543cSWenping Zhang img_buf = out_buf + offset; 5260466543cSWenping Zhang printf("image[%d] start addr=0x%p\n", i, img_buf); 5270466543cSWenping Zhang ret = convert_one_image(in_path, img_buf, offset, 5280466543cSWenping Zhang &logo_hdr->img_hdr[i], type); 5290466543cSWenping Zhang if (ret < 0) { 5300466543cSWenping Zhang printf("Convert image[%d] failed, type is %d\n", 5310466543cSWenping Zhang i, type); 5320466543cSWenping Zhang break; 5330466543cSWenping Zhang } 5340466543cSWenping Zhang } 5350466543cSWenping Zhang 5360466543cSWenping Zhang if (ret == 0) { 5370466543cSWenping Zhang struct logo_part_header *part_hdr = &logo_hdr->part_hdr; 5380466543cSWenping Zhang 5390466543cSWenping Zhang total_size = hdr_size + (i - 1) * one_img_size + 5400466543cSWenping Zhang screen_h * screen_w / 2; 5410466543cSWenping Zhang 5420466543cSWenping Zhang //convert success, write header data. 5430466543cSWenping Zhang part_hdr->magic[0] = 'R'; 5440466543cSWenping Zhang part_hdr->magic[1] = 'K'; 5450466543cSWenping Zhang part_hdr->magic[2] = 'E'; 5460466543cSWenping Zhang part_hdr->magic[3] = 'L'; 5470466543cSWenping Zhang part_hdr->totoal_size = total_size; 5480466543cSWenping Zhang part_hdr->screen_width = screen_w; 5490466543cSWenping Zhang part_hdr->screen_height = screen_h; 5500466543cSWenping Zhang part_hdr->logo_count = i; 5510466543cSWenping Zhang printf("screen w=%d, h=%d, total_size=%d\n", 5520466543cSWenping Zhang screen_w, screen_h, total_size); 5530466543cSWenping Zhang memcpy(part_hdr->version, version, 4); 5540466543cSWenping Zhang 5550466543cSWenping Zhang // write to output file 5560466543cSWenping Zhang ret = fwrite(out_buf, total_size, 1, file); 5570466543cSWenping Zhang if (ret != 1) 5580466543cSWenping Zhang fprintf(stderr, "write image to file %s failed\n", 5590466543cSWenping Zhang out_path); 5600466543cSWenping Zhang } 5610466543cSWenping Zhang 5620466543cSWenping Zhang deinit_grayscale_logo_buf(out_buf); 5630466543cSWenping Zhang ret = fclose(file); 5640466543cSWenping Zhang if (ret != 0) 5650466543cSWenping Zhang printf("Close file[%s] failed, err=%d\n", out_path, ret); 5660466543cSWenping Zhang file = NULL; 5670466543cSWenping Zhang return ret; 5680466543cSWenping Zhang } 5690466543cSWenping Zhang 570