162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Convert a logo in ASCII PNM format to C source suitable for inclusion in 462306a36Sopenharmony_ci * the Linux kernel 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * (C) Copyright 2001-2003 by Geert Uytterhoeven <geert@linux-m68k.org> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <ctype.h> 1062306a36Sopenharmony_ci#include <errno.h> 1162306a36Sopenharmony_ci#include <stdarg.h> 1262306a36Sopenharmony_ci#include <stdio.h> 1362306a36Sopenharmony_ci#include <stdlib.h> 1462306a36Sopenharmony_ci#include <string.h> 1562306a36Sopenharmony_ci#include <unistd.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistatic const char *programname; 1962306a36Sopenharmony_cistatic const char *filename; 2062306a36Sopenharmony_cistatic const char *logoname = "linux_logo"; 2162306a36Sopenharmony_cistatic const char *outputname; 2262306a36Sopenharmony_cistatic FILE *out; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define LINUX_LOGO_MONO 1 /* monochrome black/white */ 2662306a36Sopenharmony_ci#define LINUX_LOGO_VGA16 2 /* 16 colors VGA text palette */ 2762306a36Sopenharmony_ci#define LINUX_LOGO_CLUT224 3 /* 224 colors */ 2862306a36Sopenharmony_ci#define LINUX_LOGO_GRAY256 4 /* 256 levels grayscale */ 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic const char *logo_types[LINUX_LOGO_GRAY256+1] = { 3162306a36Sopenharmony_ci [LINUX_LOGO_MONO] = "LINUX_LOGO_MONO", 3262306a36Sopenharmony_ci [LINUX_LOGO_VGA16] = "LINUX_LOGO_VGA16", 3362306a36Sopenharmony_ci [LINUX_LOGO_CLUT224] = "LINUX_LOGO_CLUT224", 3462306a36Sopenharmony_ci [LINUX_LOGO_GRAY256] = "LINUX_LOGO_GRAY256" 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#define MAX_LINUX_LOGO_COLORS 224 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistruct color { 4062306a36Sopenharmony_ci unsigned char red; 4162306a36Sopenharmony_ci unsigned char green; 4262306a36Sopenharmony_ci unsigned char blue; 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic const struct color clut_vga16[16] = { 4662306a36Sopenharmony_ci { 0x00, 0x00, 0x00 }, 4762306a36Sopenharmony_ci { 0x00, 0x00, 0xaa }, 4862306a36Sopenharmony_ci { 0x00, 0xaa, 0x00 }, 4962306a36Sopenharmony_ci { 0x00, 0xaa, 0xaa }, 5062306a36Sopenharmony_ci { 0xaa, 0x00, 0x00 }, 5162306a36Sopenharmony_ci { 0xaa, 0x00, 0xaa }, 5262306a36Sopenharmony_ci { 0xaa, 0x55, 0x00 }, 5362306a36Sopenharmony_ci { 0xaa, 0xaa, 0xaa }, 5462306a36Sopenharmony_ci { 0x55, 0x55, 0x55 }, 5562306a36Sopenharmony_ci { 0x55, 0x55, 0xff }, 5662306a36Sopenharmony_ci { 0x55, 0xff, 0x55 }, 5762306a36Sopenharmony_ci { 0x55, 0xff, 0xff }, 5862306a36Sopenharmony_ci { 0xff, 0x55, 0x55 }, 5962306a36Sopenharmony_ci { 0xff, 0x55, 0xff }, 6062306a36Sopenharmony_ci { 0xff, 0xff, 0x55 }, 6162306a36Sopenharmony_ci { 0xff, 0xff, 0xff }, 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic int logo_type = LINUX_LOGO_CLUT224; 6662306a36Sopenharmony_cistatic unsigned int logo_width; 6762306a36Sopenharmony_cistatic unsigned int logo_height; 6862306a36Sopenharmony_cistatic struct color **logo_data; 6962306a36Sopenharmony_cistatic struct color logo_clut[MAX_LINUX_LOGO_COLORS]; 7062306a36Sopenharmony_cistatic unsigned int logo_clutsize; 7162306a36Sopenharmony_cistatic int is_plain_pbm = 0; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic void die(const char *fmt, ...) 7462306a36Sopenharmony_ci__attribute__((noreturn)) __attribute((format (printf, 1, 2))); 7562306a36Sopenharmony_cistatic void usage(void) __attribute((noreturn)); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistatic unsigned int get_number(FILE *fp) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci int c, val; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci /* Skip leading whitespace */ 8362306a36Sopenharmony_ci do { 8462306a36Sopenharmony_ci c = fgetc(fp); 8562306a36Sopenharmony_ci if (c == EOF) 8662306a36Sopenharmony_ci die("%s: end of file\n", filename); 8762306a36Sopenharmony_ci if (c == '#') { 8862306a36Sopenharmony_ci /* Ignore comments 'till end of line */ 8962306a36Sopenharmony_ci do { 9062306a36Sopenharmony_ci c = fgetc(fp); 9162306a36Sopenharmony_ci if (c == EOF) 9262306a36Sopenharmony_ci die("%s: end of file\n", filename); 9362306a36Sopenharmony_ci } while (c != '\n'); 9462306a36Sopenharmony_ci } 9562306a36Sopenharmony_ci } while (isspace(c)); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci /* Parse decimal number */ 9862306a36Sopenharmony_ci val = 0; 9962306a36Sopenharmony_ci while (isdigit(c)) { 10062306a36Sopenharmony_ci val = 10*val+c-'0'; 10162306a36Sopenharmony_ci /* some PBM are 'broken'; GiMP for example exports a PBM without space 10262306a36Sopenharmony_ci * between the digits. This is Ok cause we know a PBM can only have a '1' 10362306a36Sopenharmony_ci * or a '0' for the digit. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_ci if (is_plain_pbm) 10662306a36Sopenharmony_ci break; 10762306a36Sopenharmony_ci c = fgetc(fp); 10862306a36Sopenharmony_ci if (c == EOF) 10962306a36Sopenharmony_ci die("%s: end of file\n", filename); 11062306a36Sopenharmony_ci } 11162306a36Sopenharmony_ci return val; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic unsigned int get_number255(FILE *fp, unsigned int maxval) 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci unsigned int val = get_number(fp); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci return (255*val+maxval/2)/maxval; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic void read_image(void) 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci FILE *fp; 12462306a36Sopenharmony_ci unsigned int i, j; 12562306a36Sopenharmony_ci int magic; 12662306a36Sopenharmony_ci unsigned int maxval; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci /* open image file */ 12962306a36Sopenharmony_ci fp = fopen(filename, "r"); 13062306a36Sopenharmony_ci if (!fp) 13162306a36Sopenharmony_ci die("Cannot open file %s: %s\n", filename, strerror(errno)); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* check file type and read file header */ 13462306a36Sopenharmony_ci magic = fgetc(fp); 13562306a36Sopenharmony_ci if (magic != 'P') 13662306a36Sopenharmony_ci die("%s is not a PNM file\n", filename); 13762306a36Sopenharmony_ci magic = fgetc(fp); 13862306a36Sopenharmony_ci switch (magic) { 13962306a36Sopenharmony_ci case '1': 14062306a36Sopenharmony_ci case '2': 14162306a36Sopenharmony_ci case '3': 14262306a36Sopenharmony_ci /* Plain PBM/PGM/PPM */ 14362306a36Sopenharmony_ci break; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci case '4': 14662306a36Sopenharmony_ci case '5': 14762306a36Sopenharmony_ci case '6': 14862306a36Sopenharmony_ci /* Binary PBM/PGM/PPM */ 14962306a36Sopenharmony_ci die("%s: Binary PNM is not supported\n" 15062306a36Sopenharmony_ci "Use pnmnoraw(1) to convert it to ASCII PNM\n", filename); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci default: 15362306a36Sopenharmony_ci die("%s is not a PNM file\n", filename); 15462306a36Sopenharmony_ci } 15562306a36Sopenharmony_ci logo_width = get_number(fp); 15662306a36Sopenharmony_ci logo_height = get_number(fp); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* allocate image data */ 15962306a36Sopenharmony_ci logo_data = (struct color **)malloc(logo_height*sizeof(struct color *)); 16062306a36Sopenharmony_ci if (!logo_data) 16162306a36Sopenharmony_ci die("%s\n", strerror(errno)); 16262306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) { 16362306a36Sopenharmony_ci logo_data[i] = malloc(logo_width*sizeof(struct color)); 16462306a36Sopenharmony_ci if (!logo_data[i]) 16562306a36Sopenharmony_ci die("%s\n", strerror(errno)); 16662306a36Sopenharmony_ci } 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci /* read image data */ 16962306a36Sopenharmony_ci switch (magic) { 17062306a36Sopenharmony_ci case '1': 17162306a36Sopenharmony_ci /* Plain PBM */ 17262306a36Sopenharmony_ci is_plain_pbm = 1; 17362306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 17462306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) 17562306a36Sopenharmony_ci logo_data[i][j].red = logo_data[i][j].green = 17662306a36Sopenharmony_ci logo_data[i][j].blue = 255*(1-get_number(fp)); 17762306a36Sopenharmony_ci break; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci case '2': 18062306a36Sopenharmony_ci /* Plain PGM */ 18162306a36Sopenharmony_ci maxval = get_number(fp); 18262306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 18362306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) 18462306a36Sopenharmony_ci logo_data[i][j].red = logo_data[i][j].green = 18562306a36Sopenharmony_ci logo_data[i][j].blue = get_number255(fp, maxval); 18662306a36Sopenharmony_ci break; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci case '3': 18962306a36Sopenharmony_ci /* Plain PPM */ 19062306a36Sopenharmony_ci maxval = get_number(fp); 19162306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 19262306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) { 19362306a36Sopenharmony_ci logo_data[i][j].red = get_number255(fp, maxval); 19462306a36Sopenharmony_ci logo_data[i][j].green = get_number255(fp, maxval); 19562306a36Sopenharmony_ci logo_data[i][j].blue = get_number255(fp, maxval); 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci break; 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci /* close file */ 20162306a36Sopenharmony_ci fclose(fp); 20262306a36Sopenharmony_ci} 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic inline int is_black(struct color c) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci return c.red == 0 && c.green == 0 && c.blue == 0; 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cistatic inline int is_white(struct color c) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci return c.red == 255 && c.green == 255 && c.blue == 255; 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_cistatic inline int is_gray(struct color c) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci return c.red == c.green && c.red == c.blue; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic inline int is_equal(struct color c1, struct color c2) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci return c1.red == c2.red && c1.green == c2.green && c1.blue == c2.blue; 22262306a36Sopenharmony_ci} 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistatic void write_header(void) 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci /* open logo file */ 22762306a36Sopenharmony_ci if (outputname) { 22862306a36Sopenharmony_ci out = fopen(outputname, "w"); 22962306a36Sopenharmony_ci if (!out) 23062306a36Sopenharmony_ci die("Cannot create file %s: %s\n", outputname, strerror(errno)); 23162306a36Sopenharmony_ci } else { 23262306a36Sopenharmony_ci out = stdout; 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci fputs("/*\n", out); 23662306a36Sopenharmony_ci fputs(" * DO NOT EDIT THIS FILE!\n", out); 23762306a36Sopenharmony_ci fputs(" *\n", out); 23862306a36Sopenharmony_ci fprintf(out, " * It was automatically generated from %s\n", filename); 23962306a36Sopenharmony_ci fputs(" *\n", out); 24062306a36Sopenharmony_ci fprintf(out, " * Linux logo %s\n", logoname); 24162306a36Sopenharmony_ci fputs(" */\n\n", out); 24262306a36Sopenharmony_ci fputs("#include <linux/linux_logo.h>\n\n", out); 24362306a36Sopenharmony_ci fprintf(out, "static unsigned char %s_data[] __initdata = {\n", 24462306a36Sopenharmony_ci logoname); 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic void write_footer(void) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci fputs("\n};\n\n", out); 25062306a36Sopenharmony_ci fprintf(out, "const struct linux_logo %s __initconst = {\n", logoname); 25162306a36Sopenharmony_ci fprintf(out, "\t.type\t\t= %s,\n", logo_types[logo_type]); 25262306a36Sopenharmony_ci fprintf(out, "\t.width\t\t= %d,\n", logo_width); 25362306a36Sopenharmony_ci fprintf(out, "\t.height\t\t= %d,\n", logo_height); 25462306a36Sopenharmony_ci if (logo_type == LINUX_LOGO_CLUT224) { 25562306a36Sopenharmony_ci fprintf(out, "\t.clutsize\t= %d,\n", logo_clutsize); 25662306a36Sopenharmony_ci fprintf(out, "\t.clut\t\t= %s_clut,\n", logoname); 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci fprintf(out, "\t.data\t\t= %s_data\n", logoname); 25962306a36Sopenharmony_ci fputs("};\n\n", out); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci /* close logo file */ 26262306a36Sopenharmony_ci if (outputname) 26362306a36Sopenharmony_ci fclose(out); 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic int write_hex_cnt; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_cistatic void write_hex(unsigned char byte) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci if (write_hex_cnt % 12) 27162306a36Sopenharmony_ci fprintf(out, ", 0x%02x", byte); 27262306a36Sopenharmony_ci else if (write_hex_cnt) 27362306a36Sopenharmony_ci fprintf(out, ",\n\t0x%02x", byte); 27462306a36Sopenharmony_ci else 27562306a36Sopenharmony_ci fprintf(out, "\t0x%02x", byte); 27662306a36Sopenharmony_ci write_hex_cnt++; 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic void write_logo_mono(void) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci unsigned int i, j; 28262306a36Sopenharmony_ci unsigned char val, bit; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* validate image */ 28562306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 28662306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) 28762306a36Sopenharmony_ci if (!is_black(logo_data[i][j]) && !is_white(logo_data[i][j])) 28862306a36Sopenharmony_ci die("Image must be monochrome\n"); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci /* write file header */ 29162306a36Sopenharmony_ci write_header(); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci /* write logo data */ 29462306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) { 29562306a36Sopenharmony_ci for (j = 0; j < logo_width;) { 29662306a36Sopenharmony_ci for (val = 0, bit = 0x80; bit && j < logo_width; j++, bit >>= 1) 29762306a36Sopenharmony_ci if (logo_data[i][j].red) 29862306a36Sopenharmony_ci val |= bit; 29962306a36Sopenharmony_ci write_hex(val); 30062306a36Sopenharmony_ci } 30162306a36Sopenharmony_ci } 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci /* write logo structure and file footer */ 30462306a36Sopenharmony_ci write_footer(); 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic void write_logo_vga16(void) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci unsigned int i, j, k; 31062306a36Sopenharmony_ci unsigned char val; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci /* validate image */ 31362306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 31462306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) { 31562306a36Sopenharmony_ci for (k = 0; k < 16; k++) 31662306a36Sopenharmony_ci if (is_equal(logo_data[i][j], clut_vga16[k])) 31762306a36Sopenharmony_ci break; 31862306a36Sopenharmony_ci if (k == 16) 31962306a36Sopenharmony_ci die("Image must use the 16 console colors only\n" 32062306a36Sopenharmony_ci "Use ppmquant(1) -map clut_vga16.ppm to reduce the number " 32162306a36Sopenharmony_ci "of colors\n"); 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci /* write file header */ 32562306a36Sopenharmony_ci write_header(); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* write logo data */ 32862306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 32962306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) { 33062306a36Sopenharmony_ci for (k = 0; k < 16; k++) 33162306a36Sopenharmony_ci if (is_equal(logo_data[i][j], clut_vga16[k])) 33262306a36Sopenharmony_ci break; 33362306a36Sopenharmony_ci val = k<<4; 33462306a36Sopenharmony_ci if (++j < logo_width) { 33562306a36Sopenharmony_ci for (k = 0; k < 16; k++) 33662306a36Sopenharmony_ci if (is_equal(logo_data[i][j], clut_vga16[k])) 33762306a36Sopenharmony_ci break; 33862306a36Sopenharmony_ci val |= k; 33962306a36Sopenharmony_ci } 34062306a36Sopenharmony_ci write_hex(val); 34162306a36Sopenharmony_ci } 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci /* write logo structure and file footer */ 34462306a36Sopenharmony_ci write_footer(); 34562306a36Sopenharmony_ci} 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_cistatic void write_logo_clut224(void) 34862306a36Sopenharmony_ci{ 34962306a36Sopenharmony_ci unsigned int i, j, k; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci /* validate image */ 35262306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 35362306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) { 35462306a36Sopenharmony_ci for (k = 0; k < logo_clutsize; k++) 35562306a36Sopenharmony_ci if (is_equal(logo_data[i][j], logo_clut[k])) 35662306a36Sopenharmony_ci break; 35762306a36Sopenharmony_ci if (k == logo_clutsize) { 35862306a36Sopenharmony_ci if (logo_clutsize == MAX_LINUX_LOGO_COLORS) 35962306a36Sopenharmony_ci die("Image has more than %d colors\n" 36062306a36Sopenharmony_ci "Use ppmquant(1) to reduce the number of colors\n", 36162306a36Sopenharmony_ci MAX_LINUX_LOGO_COLORS); 36262306a36Sopenharmony_ci logo_clut[logo_clutsize++] = logo_data[i][j]; 36362306a36Sopenharmony_ci } 36462306a36Sopenharmony_ci } 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci /* write file header */ 36762306a36Sopenharmony_ci write_header(); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci /* write logo data */ 37062306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 37162306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) { 37262306a36Sopenharmony_ci for (k = 0; k < logo_clutsize; k++) 37362306a36Sopenharmony_ci if (is_equal(logo_data[i][j], logo_clut[k])) 37462306a36Sopenharmony_ci break; 37562306a36Sopenharmony_ci write_hex(k+32); 37662306a36Sopenharmony_ci } 37762306a36Sopenharmony_ci fputs("\n};\n\n", out); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci /* write logo clut */ 38062306a36Sopenharmony_ci fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", 38162306a36Sopenharmony_ci logoname); 38262306a36Sopenharmony_ci write_hex_cnt = 0; 38362306a36Sopenharmony_ci for (i = 0; i < logo_clutsize; i++) { 38462306a36Sopenharmony_ci write_hex(logo_clut[i].red); 38562306a36Sopenharmony_ci write_hex(logo_clut[i].green); 38662306a36Sopenharmony_ci write_hex(logo_clut[i].blue); 38762306a36Sopenharmony_ci } 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci /* write logo structure and file footer */ 39062306a36Sopenharmony_ci write_footer(); 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistatic void write_logo_gray256(void) 39462306a36Sopenharmony_ci{ 39562306a36Sopenharmony_ci unsigned int i, j; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci /* validate image */ 39862306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 39962306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) 40062306a36Sopenharmony_ci if (!is_gray(logo_data[i][j])) 40162306a36Sopenharmony_ci die("Image must be grayscale\n"); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci /* write file header */ 40462306a36Sopenharmony_ci write_header(); 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci /* write logo data */ 40762306a36Sopenharmony_ci for (i = 0; i < logo_height; i++) 40862306a36Sopenharmony_ci for (j = 0; j < logo_width; j++) 40962306a36Sopenharmony_ci write_hex(logo_data[i][j].red); 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci /* write logo structure and file footer */ 41262306a36Sopenharmony_ci write_footer(); 41362306a36Sopenharmony_ci} 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_cistatic void die(const char *fmt, ...) 41662306a36Sopenharmony_ci{ 41762306a36Sopenharmony_ci va_list ap; 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci va_start(ap, fmt); 42062306a36Sopenharmony_ci vfprintf(stderr, fmt, ap); 42162306a36Sopenharmony_ci va_end(ap); 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci exit(1); 42462306a36Sopenharmony_ci} 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistatic void usage(void) 42762306a36Sopenharmony_ci{ 42862306a36Sopenharmony_ci die("\n" 42962306a36Sopenharmony_ci "Usage: %s [options] <filename>\n" 43062306a36Sopenharmony_ci "\n" 43162306a36Sopenharmony_ci "Valid options:\n" 43262306a36Sopenharmony_ci " -h : display this usage information\n" 43362306a36Sopenharmony_ci " -n <name> : specify logo name (default: linux_logo)\n" 43462306a36Sopenharmony_ci " -o <output> : output to file <output> instead of stdout\n" 43562306a36Sopenharmony_ci " -t <type> : specify logo type, one of\n" 43662306a36Sopenharmony_ci " mono : monochrome black/white\n" 43762306a36Sopenharmony_ci " vga16 : 16 colors VGA text palette\n" 43862306a36Sopenharmony_ci " clut224 : 224 colors (default)\n" 43962306a36Sopenharmony_ci " gray256 : 256 levels grayscale\n" 44062306a36Sopenharmony_ci "\n", programname); 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ciint main(int argc, char *argv[]) 44462306a36Sopenharmony_ci{ 44562306a36Sopenharmony_ci int opt; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci programname = argv[0]; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci opterr = 0; 45062306a36Sopenharmony_ci while (1) { 45162306a36Sopenharmony_ci opt = getopt(argc, argv, "hn:o:t:"); 45262306a36Sopenharmony_ci if (opt == -1) 45362306a36Sopenharmony_ci break; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci switch (opt) { 45662306a36Sopenharmony_ci case 'h': 45762306a36Sopenharmony_ci usage(); 45862306a36Sopenharmony_ci break; 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci case 'n': 46162306a36Sopenharmony_ci logoname = optarg; 46262306a36Sopenharmony_ci break; 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci case 'o': 46562306a36Sopenharmony_ci outputname = optarg; 46662306a36Sopenharmony_ci break; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci case 't': 46962306a36Sopenharmony_ci if (!strcmp(optarg, "mono")) 47062306a36Sopenharmony_ci logo_type = LINUX_LOGO_MONO; 47162306a36Sopenharmony_ci else if (!strcmp(optarg, "vga16")) 47262306a36Sopenharmony_ci logo_type = LINUX_LOGO_VGA16; 47362306a36Sopenharmony_ci else if (!strcmp(optarg, "clut224")) 47462306a36Sopenharmony_ci logo_type = LINUX_LOGO_CLUT224; 47562306a36Sopenharmony_ci else if (!strcmp(optarg, "gray256")) 47662306a36Sopenharmony_ci logo_type = LINUX_LOGO_GRAY256; 47762306a36Sopenharmony_ci else 47862306a36Sopenharmony_ci usage(); 47962306a36Sopenharmony_ci break; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci default: 48262306a36Sopenharmony_ci usage(); 48362306a36Sopenharmony_ci break; 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci } 48662306a36Sopenharmony_ci if (optind != argc-1) 48762306a36Sopenharmony_ci usage(); 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci filename = argv[optind]; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci read_image(); 49262306a36Sopenharmony_ci switch (logo_type) { 49362306a36Sopenharmony_ci case LINUX_LOGO_MONO: 49462306a36Sopenharmony_ci write_logo_mono(); 49562306a36Sopenharmony_ci break; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci case LINUX_LOGO_VGA16: 49862306a36Sopenharmony_ci write_logo_vga16(); 49962306a36Sopenharmony_ci break; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci case LINUX_LOGO_CLUT224: 50262306a36Sopenharmony_ci write_logo_clut224(); 50362306a36Sopenharmony_ci break; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci case LINUX_LOGO_GRAY256: 50662306a36Sopenharmony_ci write_logo_gray256(); 50762306a36Sopenharmony_ci break; 50862306a36Sopenharmony_ci } 50962306a36Sopenharmony_ci exit(0); 51062306a36Sopenharmony_ci} 511