18c2ecf20Sopenharmony_ci 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Convert a logo in ASCII PNM format to C source suitable for inclusion in 48c2ecf20Sopenharmony_ci * the Linux kernel 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * -------------------------------------------------------------------------- 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 118c2ecf20Sopenharmony_ci * License. See the file COPYING in the main directory of the Linux 128c2ecf20Sopenharmony_ci * distribution for more details. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <ctype.h> 168c2ecf20Sopenharmony_ci#include <errno.h> 178c2ecf20Sopenharmony_ci#include <stdarg.h> 188c2ecf20Sopenharmony_ci#include <stdio.h> 198c2ecf20Sopenharmony_ci#include <stdlib.h> 208c2ecf20Sopenharmony_ci#include <string.h> 218c2ecf20Sopenharmony_ci#include <unistd.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic const char *programname; 258c2ecf20Sopenharmony_cistatic const char *filename; 268c2ecf20Sopenharmony_cistatic const char *logoname = "linux_logo"; 278c2ecf20Sopenharmony_cistatic const char *outputname; 288c2ecf20Sopenharmony_cistatic FILE *out; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define LINUX_LOGO_MONO 1 /* monochrome black/white */ 328c2ecf20Sopenharmony_ci#define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */ 338c2ecf20Sopenharmony_ci#define LINUX_LOGO_CLUT224 3 /* 224 colors */ 348c2ecf20Sopenharmony_ci#define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */ 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic const char *logo_types[LINUX_LOGO_GRAY256+1] = { 378c2ecf20Sopenharmony_ci [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO", 388c2ecf20Sopenharmony_ci [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16", 398c2ecf20Sopenharmony_ci [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224", 408c2ecf20Sopenharmony_ci [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256" 418c2ecf20Sopenharmony_ci}; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define MAX_LINUX_LOGO_COLORS 224 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistruct color { 468c2ecf20Sopenharmony_ci unsigned char red; 478c2ecf20Sopenharmony_ci unsigned char green; 488c2ecf20Sopenharmony_ci unsigned char blue; 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic const struct color clut_vga16[16] = { 528c2ecf20Sopenharmony_ci { 0x00, 0x00, 0x00 }, 538c2ecf20Sopenharmony_ci { 0x00, 0x00, 0xaa }, 548c2ecf20Sopenharmony_ci { 0x00, 0xaa, 0x00 }, 558c2ecf20Sopenharmony_ci { 0x00, 0xaa, 0xaa }, 568c2ecf20Sopenharmony_ci { 0xaa, 0x00, 0x00 }, 578c2ecf20Sopenharmony_ci { 0xaa, 0x00, 0xaa }, 588c2ecf20Sopenharmony_ci { 0xaa, 0x55, 0x00 }, 598c2ecf20Sopenharmony_ci { 0xaa, 0xaa, 0xaa }, 608c2ecf20Sopenharmony_ci { 0x55, 0x55, 0x55 }, 618c2ecf20Sopenharmony_ci { 0x55, 0x55, 0xff }, 628c2ecf20Sopenharmony_ci { 0x55, 0xff, 0x55 }, 638c2ecf20Sopenharmony_ci { 0x55, 0xff, 0xff }, 648c2ecf20Sopenharmony_ci { 0xff, 0x55, 0x55 }, 658c2ecf20Sopenharmony_ci { 0xff, 0x55, 0xff }, 668c2ecf20Sopenharmony_ci { 0xff, 0xff, 0x55 }, 678c2ecf20Sopenharmony_ci { 0xff, 0xff, 0xff }, 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic int logo_type = LINUX_LOGO_CLUT224; 728c2ecf20Sopenharmony_cistatic unsigned int logo_width; 738c2ecf20Sopenharmony_cistatic unsigned int logo_height; 748c2ecf20Sopenharmony_cistatic struct color **logo_data; 758c2ecf20Sopenharmony_cistatic struct color logo_clut[MAX_LINUX_LOGO_COLORS]; 768c2ecf20Sopenharmony_cistatic unsigned int logo_clutsize; 778c2ecf20Sopenharmony_cistatic int is_plain_pbm = 0; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic void die(const char *fmt, ...) 808c2ecf20Sopenharmony_ci __attribute__ ((noreturn)) __attribute ((format (printf, 1, 2))); 818c2ecf20Sopenharmony_cistatic void usage(void) __attribute ((noreturn)); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistatic unsigned int get_number(FILE *fp) 858c2ecf20Sopenharmony_ci{ 868c2ecf20Sopenharmony_ci int c, val; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci /* Skip leading whitespace */ 898c2ecf20Sopenharmony_ci do { 908c2ecf20Sopenharmony_ci c = fgetc(fp); 918c2ecf20Sopenharmony_ci if (c == EOF) 928c2ecf20Sopenharmony_ci die("%s: end of file\n", filename); 938c2ecf20Sopenharmony_ci if (c == '#') { 948c2ecf20Sopenharmony_ci /* Ignore comments 'till end of line */ 958c2ecf20Sopenharmony_ci do { 968c2ecf20Sopenharmony_ci c = fgetc(fp); 978c2ecf20Sopenharmony_ci if (c == EOF) 988c2ecf20Sopenharmony_ci die("%s: end of file\n", filename); 998c2ecf20Sopenharmony_ci } while (c != '\n'); 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci } while (isspace(c)); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci /* Parse decimal number */ 1048c2ecf20Sopenharmony_ci val = 0; 1058c2ecf20Sopenharmony_ci while (isdigit(c)) { 1068c2ecf20Sopenharmony_ci val = 10*val+c-'0'; 1078c2ecf20Sopenharmony_ci /* some PBM are 'broken'; GiMP for example exports a PBM without space 1088c2ecf20Sopenharmony_ci * between the digits. This is Ok cause we know a PBM can only have a '1' 1098c2ecf20Sopenharmony_ci * or a '0' for the digit. */ 1108c2ecf20Sopenharmony_ci if (is_plain_pbm) 1118c2ecf20Sopenharmony_ci break; 1128c2ecf20Sopenharmony_ci c = fgetc(fp); 1138c2ecf20Sopenharmony_ci if (c == EOF) 1148c2ecf20Sopenharmony_ci die("%s: end of file\n", filename); 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci return val; 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistatic unsigned int get_number255(FILE *fp, unsigned int maxval) 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci unsigned int val = get_number(fp); 1228c2ecf20Sopenharmony_ci return (255*val+maxval/2)/maxval; 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistatic void read_image(void) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci FILE *fp; 1288c2ecf20Sopenharmony_ci unsigned int i, j; 1298c2ecf20Sopenharmony_ci int magic; 1308c2ecf20Sopenharmony_ci unsigned int maxval; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci /* open image file */ 1338c2ecf20Sopenharmony_ci fp = fopen(filename, "r"); 1348c2ecf20Sopenharmony_ci if (!fp) 1358c2ecf20Sopenharmony_ci die("Cannot open file %s: %s\n", filename, strerror(errno)); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci /* check file type and read file header */ 1388c2ecf20Sopenharmony_ci magic = fgetc(fp); 1398c2ecf20Sopenharmony_ci if (magic != 'P') 1408c2ecf20Sopenharmony_ci die("%s is not a PNM file\n", filename); 1418c2ecf20Sopenharmony_ci magic = fgetc(fp); 1428c2ecf20Sopenharmony_ci switch (magic) { 1438c2ecf20Sopenharmony_ci case '1': 1448c2ecf20Sopenharmony_ci case '2': 1458c2ecf20Sopenharmony_ci case '3': 1468c2ecf20Sopenharmony_ci /* Plain PBM/PGM/PPM */ 1478c2ecf20Sopenharmony_ci break; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci case '4': 1508c2ecf20Sopenharmony_ci case '5': 1518c2ecf20Sopenharmony_ci case '6': 1528c2ecf20Sopenharmony_ci /* Binary PBM/PGM/PPM */ 1538c2ecf20Sopenharmony_ci die("%s: Binary PNM is not supported\n" 1548c2ecf20Sopenharmony_ci "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci default: 1578c2ecf20Sopenharmony_ci die("%s is not a PNM file\n", filename); 1588c2ecf20Sopenharmony_ci } 1598c2ecf20Sopenharmony_ci logo_width = get_number(fp); 1608c2ecf20Sopenharmony_ci logo_height = get_number(fp); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci /* allocate image data */ 1638c2ecf20Sopenharmony_ci logo_data = (struct color **)malloc(logo_height*sizeof(struct color *)); 1648c2ecf20Sopenharmony_ci if (!logo_data) 1658c2ecf20Sopenharmony_ci die("%s\n", strerror(errno)); 1668c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) { 1678c2ecf20Sopenharmony_ci logo_data[i] = malloc(logo_width*sizeof(struct color)); 1688c2ecf20Sopenharmony_ci if (!logo_data[i]) 1698c2ecf20Sopenharmony_ci die("%s\n", strerror(errno)); 1708c2ecf20Sopenharmony_ci } 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci /* read image data */ 1738c2ecf20Sopenharmony_ci switch (magic) { 1748c2ecf20Sopenharmony_ci case '1': 1758c2ecf20Sopenharmony_ci /* Plain PBM */ 1768c2ecf20Sopenharmony_ci is_plain_pbm = 1; 1778c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 1788c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) 1798c2ecf20Sopenharmony_ci logo_data[i][j].red = logo_data[i][j].green = 1808c2ecf20Sopenharmony_ci logo_data[i][j].blue = 255*(1-get_number(fp)); 1818c2ecf20Sopenharmony_ci break; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci case '2': 1848c2ecf20Sopenharmony_ci /* Plain PGM */ 1858c2ecf20Sopenharmony_ci maxval = get_number(fp); 1868c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 1878c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) 1888c2ecf20Sopenharmony_ci logo_data[i][j].red = logo_data[i][j].green = 1898c2ecf20Sopenharmony_ci logo_data[i][j].blue = get_number255(fp, maxval); 1908c2ecf20Sopenharmony_ci break; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci case '3': 1938c2ecf20Sopenharmony_ci /* Plain PPM */ 1948c2ecf20Sopenharmony_ci maxval = get_number(fp); 1958c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 1968c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) { 1978c2ecf20Sopenharmony_ci logo_data[i][j].red = get_number255(fp, maxval); 1988c2ecf20Sopenharmony_ci logo_data[i][j].green = get_number255(fp, maxval); 1998c2ecf20Sopenharmony_ci logo_data[i][j].blue = get_number255(fp, maxval); 2008c2ecf20Sopenharmony_ci } 2018c2ecf20Sopenharmony_ci break; 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci /* close file */ 2058c2ecf20Sopenharmony_ci fclose(fp); 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistatic inline int is_black(struct color c) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci return c.red == 0 && c.green == 0 && c.blue == 0; 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic inline int is_white(struct color c) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci return c.red == 255 && c.green == 255 && c.blue == 255; 2168c2ecf20Sopenharmony_ci} 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_cistatic inline int is_gray(struct color c) 2198c2ecf20Sopenharmony_ci{ 2208c2ecf20Sopenharmony_ci return c.red == c.green && c.red == c.blue; 2218c2ecf20Sopenharmony_ci} 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_cistatic inline int is_equal(struct color c1, struct color c2) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue; 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_cistatic void write_header(void) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci /* open logo file */ 2318c2ecf20Sopenharmony_ci if (outputname) { 2328c2ecf20Sopenharmony_ci out = fopen(outputname, "w"); 2338c2ecf20Sopenharmony_ci if (!out) 2348c2ecf20Sopenharmony_ci die("Cannot create file %s: %s\n", outputname, strerror(errno)); 2358c2ecf20Sopenharmony_ci } else { 2368c2ecf20Sopenharmony_ci out = stdout; 2378c2ecf20Sopenharmony_ci } 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci fputs("/*\n", out); 2408c2ecf20Sopenharmony_ci fputs(" * DO NOT EDIT THIS FILE!\n", out); 2418c2ecf20Sopenharmony_ci fputs(" *\n", out); 2428c2ecf20Sopenharmony_ci fprintf(out, " * It was automatically generated from %s\n", filename); 2438c2ecf20Sopenharmony_ci fputs(" *\n", out); 2448c2ecf20Sopenharmony_ci fprintf(out, " * Linux logo %s\n", logoname); 2458c2ecf20Sopenharmony_ci fputs(" */\n\n", out); 2468c2ecf20Sopenharmony_ci fputs("#include <linux/linux_logo.h>\n\n", out); 2478c2ecf20Sopenharmony_ci fprintf(out, "static unsigned char %s_data[] __initdata = {\n", 2488c2ecf20Sopenharmony_ci logoname); 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic void write_footer(void) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci fputs("\n};\n\n", out); 2548c2ecf20Sopenharmony_ci fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname); 2558c2ecf20Sopenharmony_ci fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]); 2568c2ecf20Sopenharmony_ci fprintf(out, "\t.width\t\t= %d,\n", logo_width); 2578c2ecf20Sopenharmony_ci fprintf(out, "\t.height\t\t= %d,\n", logo_height); 2588c2ecf20Sopenharmony_ci if (logo_type == LINUX_LOGO_CLUT224) { 2598c2ecf20Sopenharmony_ci fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize); 2608c2ecf20Sopenharmony_ci fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname); 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci fprintf(out, "\t.data\t\t= %s_data\n", logoname); 2638c2ecf20Sopenharmony_ci fputs("};\n\n", out); 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci /* close logo file */ 2668c2ecf20Sopenharmony_ci if (outputname) 2678c2ecf20Sopenharmony_ci fclose(out); 2688c2ecf20Sopenharmony_ci} 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic int write_hex_cnt; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cistatic void write_hex(unsigned char byte) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci if (write_hex_cnt % 12) 2758c2ecf20Sopenharmony_ci fprintf(out, ", 0x%02x", byte); 2768c2ecf20Sopenharmony_ci else if (write_hex_cnt) 2778c2ecf20Sopenharmony_ci fprintf(out, ",\n\t0x%02x", byte); 2788c2ecf20Sopenharmony_ci else 2798c2ecf20Sopenharmony_ci fprintf(out, "\t0x%02x", byte); 2808c2ecf20Sopenharmony_ci write_hex_cnt++; 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic void write_logo_mono(void) 2848c2ecf20Sopenharmony_ci{ 2858c2ecf20Sopenharmony_ci unsigned int i, j; 2868c2ecf20Sopenharmony_ci unsigned char val, bit; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci /* validate image */ 2898c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 2908c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) 2918c2ecf20Sopenharmony_ci if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j])) 2928c2ecf20Sopenharmony_ci die("Image must be monochrome\n"); 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci /* write file header */ 2958c2ecf20Sopenharmony_ci write_header(); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci /* write logo data */ 2988c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) { 2998c2ecf20Sopenharmony_ci for (j = 0; j < logo_width;) { 3008c2ecf20Sopenharmony_ci for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1) 3018c2ecf20Sopenharmony_ci if (logo_data[i][j].red) 3028c2ecf20Sopenharmony_ci val |= bit; 3038c2ecf20Sopenharmony_ci write_hex(val); 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci } 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci /* write logo structure and file footer */ 3088c2ecf20Sopenharmony_ci write_footer(); 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic void write_logo_vga16(void) 3128c2ecf20Sopenharmony_ci{ 3138c2ecf20Sopenharmony_ci unsigned int i, j, k; 3148c2ecf20Sopenharmony_ci unsigned char val; 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci /* validate image */ 3178c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 3188c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) { 3198c2ecf20Sopenharmony_ci for (k = 0; k < 16; k++) 3208c2ecf20Sopenharmony_ci if (is_equal(logo_data[i][j], clut_vga16[k])) 3218c2ecf20Sopenharmony_ci break; 3228c2ecf20Sopenharmony_ci if (k == 16) 3238c2ecf20Sopenharmony_ci die("Image must use the 16 console colors only\n" 3248c2ecf20Sopenharmony_ci "Use ppmquant(1) -map clut_vga16.ppm to reduce the number " 3258c2ecf20Sopenharmony_ci "of colors\n"); 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci /* write file header */ 3298c2ecf20Sopenharmony_ci write_header(); 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci /* write logo data */ 3328c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 3338c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) { 3348c2ecf20Sopenharmony_ci for (k = 0; k < 16; k++) 3358c2ecf20Sopenharmony_ci if (is_equal(logo_data[i][j], clut_vga16[k])) 3368c2ecf20Sopenharmony_ci break; 3378c2ecf20Sopenharmony_ci val = k<<4; 3388c2ecf20Sopenharmony_ci if (++j < logo_width) { 3398c2ecf20Sopenharmony_ci for (k = 0; k < 16; k++) 3408c2ecf20Sopenharmony_ci if (is_equal(logo_data[i][j], clut_vga16[k])) 3418c2ecf20Sopenharmony_ci break; 3428c2ecf20Sopenharmony_ci val |= k; 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci write_hex(val); 3458c2ecf20Sopenharmony_ci } 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci /* write logo structure and file footer */ 3488c2ecf20Sopenharmony_ci write_footer(); 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cistatic void write_logo_clut224(void) 3528c2ecf20Sopenharmony_ci{ 3538c2ecf20Sopenharmony_ci unsigned int i, j, k; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci /* validate image */ 3568c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 3578c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) { 3588c2ecf20Sopenharmony_ci for (k = 0; k < logo_clutsize; k++) 3598c2ecf20Sopenharmony_ci if (is_equal(logo_data[i][j], logo_clut[k])) 3608c2ecf20Sopenharmony_ci break; 3618c2ecf20Sopenharmony_ci if (k == logo_clutsize) { 3628c2ecf20Sopenharmony_ci if (logo_clutsize == MAX_LINUX_LOGO_COLORS) 3638c2ecf20Sopenharmony_ci die("Image has more than %d colors\n" 3648c2ecf20Sopenharmony_ci "Use ppmquant(1) to reduce the number of colors\n", 3658c2ecf20Sopenharmony_ci MAX_LINUX_LOGO_COLORS); 3668c2ecf20Sopenharmony_ci logo_clut[logo_clutsize++] = logo_data[i][j]; 3678c2ecf20Sopenharmony_ci } 3688c2ecf20Sopenharmony_ci } 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci /* write file header */ 3718c2ecf20Sopenharmony_ci write_header(); 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci /* write logo data */ 3748c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 3758c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) { 3768c2ecf20Sopenharmony_ci for (k = 0; k < logo_clutsize; k++) 3778c2ecf20Sopenharmony_ci if (is_equal(logo_data[i][j], logo_clut[k])) 3788c2ecf20Sopenharmony_ci break; 3798c2ecf20Sopenharmony_ci write_hex(k+32); 3808c2ecf20Sopenharmony_ci } 3818c2ecf20Sopenharmony_ci fputs("\n};\n\n", out); 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci /* write logo clut */ 3848c2ecf20Sopenharmony_ci fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", 3858c2ecf20Sopenharmony_ci logoname); 3868c2ecf20Sopenharmony_ci write_hex_cnt = 0; 3878c2ecf20Sopenharmony_ci for (i = 0; i < logo_clutsize; i++) { 3888c2ecf20Sopenharmony_ci write_hex(logo_clut[i].red); 3898c2ecf20Sopenharmony_ci write_hex(logo_clut[i].green); 3908c2ecf20Sopenharmony_ci write_hex(logo_clut[i].blue); 3918c2ecf20Sopenharmony_ci } 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* write logo structure and file footer */ 3948c2ecf20Sopenharmony_ci write_footer(); 3958c2ecf20Sopenharmony_ci} 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_cistatic void write_logo_gray256(void) 3988c2ecf20Sopenharmony_ci{ 3998c2ecf20Sopenharmony_ci unsigned int i, j; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci /* validate image */ 4028c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 4038c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) 4048c2ecf20Sopenharmony_ci if (!is_gray(logo_data[i][j])) 4058c2ecf20Sopenharmony_ci die("Image must be grayscale\n"); 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci /* write file header */ 4088c2ecf20Sopenharmony_ci write_header(); 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci /* write logo data */ 4118c2ecf20Sopenharmony_ci for (i = 0; i < logo_height; i++) 4128c2ecf20Sopenharmony_ci for (j = 0; j < logo_width; j++) 4138c2ecf20Sopenharmony_ci write_hex(logo_data[i][j].red); 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci /* write logo structure and file footer */ 4168c2ecf20Sopenharmony_ci write_footer(); 4178c2ecf20Sopenharmony_ci} 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_cistatic void die(const char *fmt, ...) 4208c2ecf20Sopenharmony_ci{ 4218c2ecf20Sopenharmony_ci va_list ap; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci va_start(ap, fmt); 4248c2ecf20Sopenharmony_ci vfprintf(stderr, fmt, ap); 4258c2ecf20Sopenharmony_ci va_end(ap); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci exit(1); 4288c2ecf20Sopenharmony_ci} 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_cistatic void usage(void) 4318c2ecf20Sopenharmony_ci{ 4328c2ecf20Sopenharmony_ci die("\n" 4338c2ecf20Sopenharmony_ci "Usage: %s [options] <filename>\n" 4348c2ecf20Sopenharmony_ci "\n" 4358c2ecf20Sopenharmony_ci "Valid options:\n" 4368c2ecf20Sopenharmony_ci " -h : display this usage information\n" 4378c2ecf20Sopenharmony_ci " -n <name> : specify logo name (default: linux_logo)\n" 4388c2ecf20Sopenharmony_ci " -o <output> : output to file <output> instead of stdout\n" 4398c2ecf20Sopenharmony_ci " -t <type> : specify logo type, one of\n" 4408c2ecf20Sopenharmony_ci " mono : monochrome black/white\n" 4418c2ecf20Sopenharmony_ci " vga16 : 16 colors VGA text palette\n" 4428c2ecf20Sopenharmony_ci " clut224 : 224 colors (default)\n" 4438c2ecf20Sopenharmony_ci " gray256 : 256 levels grayscale\n" 4448c2ecf20Sopenharmony_ci "\n", programname); 4458c2ecf20Sopenharmony_ci} 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ciint main(int argc, char *argv[]) 4488c2ecf20Sopenharmony_ci{ 4498c2ecf20Sopenharmony_ci int opt; 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci programname = argv[0]; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci opterr = 0; 4548c2ecf20Sopenharmony_ci while (1) { 4558c2ecf20Sopenharmony_ci opt = getopt(argc, argv, "hn:o:t:"); 4568c2ecf20Sopenharmony_ci if (opt == -1) 4578c2ecf20Sopenharmony_ci break; 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci switch (opt) { 4608c2ecf20Sopenharmony_ci case 'h': 4618c2ecf20Sopenharmony_ci usage(); 4628c2ecf20Sopenharmony_ci break; 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci case 'n': 4658c2ecf20Sopenharmony_ci logoname = optarg; 4668c2ecf20Sopenharmony_ci break; 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci case 'o': 4698c2ecf20Sopenharmony_ci outputname = optarg; 4708c2ecf20Sopenharmony_ci break; 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci case 't': 4738c2ecf20Sopenharmony_ci if (!strcmp(optarg, "mono")) 4748c2ecf20Sopenharmony_ci logo_type = LINUX_LOGO_MONO; 4758c2ecf20Sopenharmony_ci else if (!strcmp(optarg, "vga16")) 4768c2ecf20Sopenharmony_ci logo_type = LINUX_LOGO_VGA16; 4778c2ecf20Sopenharmony_ci else if (!strcmp(optarg, "clut224")) 4788c2ecf20Sopenharmony_ci logo_type = LINUX_LOGO_CLUT224; 4798c2ecf20Sopenharmony_ci else if (!strcmp(optarg, "gray256")) 4808c2ecf20Sopenharmony_ci logo_type = LINUX_LOGO_GRAY256; 4818c2ecf20Sopenharmony_ci else 4828c2ecf20Sopenharmony_ci usage(); 4838c2ecf20Sopenharmony_ci break; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci default: 4868c2ecf20Sopenharmony_ci usage(); 4878c2ecf20Sopenharmony_ci break; 4888c2ecf20Sopenharmony_ci } 4898c2ecf20Sopenharmony_ci } 4908c2ecf20Sopenharmony_ci if (optind != argc-1) 4918c2ecf20Sopenharmony_ci usage(); 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci filename = argv[optind]; 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci read_image(); 4968c2ecf20Sopenharmony_ci switch (logo_type) { 4978c2ecf20Sopenharmony_ci case LINUX_LOGO_MONO: 4988c2ecf20Sopenharmony_ci write_logo_mono(); 4998c2ecf20Sopenharmony_ci break; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci case LINUX_LOGO_VGA16: 5028c2ecf20Sopenharmony_ci write_logo_vga16(); 5038c2ecf20Sopenharmony_ci break; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci case LINUX_LOGO_CLUT224: 5068c2ecf20Sopenharmony_ci write_logo_clut224(); 5078c2ecf20Sopenharmony_ci break; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci case LINUX_LOGO_GRAY256: 5108c2ecf20Sopenharmony_ci write_logo_gray256(); 5118c2ecf20Sopenharmony_ci break; 5128c2ecf20Sopenharmony_ci } 5138c2ecf20Sopenharmony_ci exit(0); 5148c2ecf20Sopenharmony_ci} 515